<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="lt">
	<id>https://wiki.eofnet.lt/w//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%5Cdev%5Cnull</id>
	<title>Žinynas - Naudotojo indėlis [lt]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.eofnet.lt/w//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%5Cdev%5Cnull"/>
	<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/wiki/Specialus:Ind%C4%97lis/%5Cdev%5Cnull"/>
	<updated>2026-04-15T05:22:00Z</updated>
	<subtitle>Naudotojo indėlis</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Nut-upsd-fake&amp;diff=9859</id>
		<title>Nut-upsd-fake</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Nut-upsd-fake&amp;diff=9859"/>
		<updated>2026-03-22T22:25:23Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: Jeigu taip atsitiko ir network ups'as sugrybavo, arba dėl kažkokių priežaščių reikia raportuoti, kad upsas gyvas ir online, galima pasinaudoti šiuo fake nut-upsd daemonu....&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Jeigu taip atsitiko ir network ups'as sugrybavo, arba dėl kažkokių priežaščių reikia raportuoti, kad upsas gyvas ir online, galima pasinaudoti šiuo fake nut-upsd daemonu...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
import socket&lt;br /&gt;
import threading&lt;br /&gt;
import datetime&lt;br /&gt;
&lt;br /&gt;
HOST = &amp;quot;0.0.0.0&amp;quot;&lt;br /&gt;
PORT = 3493&lt;br /&gt;
&lt;br /&gt;
PRIMARY_UPSNAME = &amp;quot;qnapups&amp;quot;&lt;br /&gt;
UPS_ALIASES = {&amp;quot;qnapups&amp;quot;, &amp;quot;ups&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
USERNAME = &amp;quot;monuser&amp;quot;&lt;br /&gt;
PASSWORD = &amp;quot;secret&amp;quot;&lt;br /&gt;
&lt;br /&gt;
VARS = {&lt;br /&gt;
    &amp;quot;ups.status&amp;quot;: &amp;quot;OL&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.charge&amp;quot;: &amp;quot;100&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.charge.low&amp;quot;: &amp;quot;10&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.charge.warning&amp;quot;: &amp;quot;20&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.runtime&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.runtime.low&amp;quot;: &amp;quot;300&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.voltage&amp;quot;: &amp;quot;26.9&amp;quot;,&lt;br /&gt;
    &amp;quot;battery.voltage.nominal&amp;quot;: &amp;quot;24&amp;quot;,&lt;br /&gt;
    &amp;quot;input.voltage&amp;quot;: &amp;quot;230.0&amp;quot;,&lt;br /&gt;
    &amp;quot;input.voltage.nominal&amp;quot;: &amp;quot;230&amp;quot;,&lt;br /&gt;
    &amp;quot;output.voltage&amp;quot;: &amp;quot;230.0&amp;quot;,&lt;br /&gt;
    &amp;quot;ups.load&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;ups.mfr&amp;quot;: &amp;quot;FakeNUT&amp;quot;,&lt;br /&gt;
    &amp;quot;ups.model&amp;quot;: &amp;quot;FakeQNAPUPS&amp;quot;,&lt;br /&gt;
    &amp;quot;device.type&amp;quot;: &amp;quot;ups&amp;quot;,&lt;br /&gt;
    &amp;quot;device.model&amp;quot;: &amp;quot;FakeQNAPUPS&amp;quot;,&lt;br /&gt;
    &amp;quot;driver.name&amp;quot;: &amp;quot;dummy-ups&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
def ts():&lt;br /&gt;
    return datetime.datetime.now().strftime(&amp;quot;%H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    print(f&amp;quot;[{ts()}] {msg}&amp;quot;, flush=True)&lt;br /&gt;
&lt;br /&gt;
def send_line(conn, addr, line):&lt;br /&gt;
    log(f&amp;quot;{addr} &amp;lt;&amp;lt; {line}&amp;quot;)&lt;br /&gt;
    conn.sendall((line + &amp;quot;\n&amp;quot;).encode())&lt;br /&gt;
&lt;br /&gt;
def normalize_ups_name(name: str) -&amp;gt; str:&lt;br /&gt;
    if name in UPS_ALIASES:&lt;br /&gt;
        return name&lt;br /&gt;
    return PRIMARY_UPSNAME&lt;br /&gt;
&lt;br /&gt;
def handle_client(conn, addr_tuple):&lt;br /&gt;
    addr = f&amp;quot;{addr_tuple[0]}:{addr_tuple[1]}&amp;quot;&lt;br /&gt;
    log(f&amp;quot;[+] CONNECT {addr}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    authed_user = None&lt;br /&gt;
    authed_pass = None&lt;br /&gt;
    logged_in = False&lt;br /&gt;
    tls_started = False&lt;br /&gt;
&lt;br /&gt;
    f = conn.makefile(&amp;quot;r&amp;quot;, encoding=&amp;quot;utf-8&amp;quot;, newline=&amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        for raw in f:&lt;br /&gt;
            line = raw.strip()&lt;br /&gt;
            if not line:&lt;br /&gt;
                continue&lt;br /&gt;
&lt;br /&gt;
            log(f&amp;quot;{addr} &amp;gt;&amp;gt; {line}&amp;quot;)&lt;br /&gt;
            parts = line.split()&lt;br /&gt;
            cmd = parts[0].upper()&lt;br /&gt;
&lt;br /&gt;
            if cmd == &amp;quot;VER&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;Network UPS Tools upsd 2.8.0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;NETVER&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;2.8.0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;PROTVER&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;1.3&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;STARTTLS&amp;quot;:&lt;br /&gt;
                tls_started = True&lt;br /&gt;
                send_line(conn, addr, &amp;quot;ERR FEATURE-NOT-CONFIGURED&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;LIST&amp;quot; and len(parts) &amp;gt;= 2 and parts[1].upper() == &amp;quot;UPS&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;BEGIN LIST UPS&amp;quot;)&lt;br /&gt;
                send_line(conn, addr, f'UPS qnapups &amp;quot;Fake QNAP UPS&amp;quot;')&lt;br /&gt;
                send_line(conn, addr, f'UPS ups &amp;quot;Fake Synology Default UPS&amp;quot;')&lt;br /&gt;
                send_line(conn, addr, &amp;quot;END LIST UPS&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;USERNAME&amp;quot; and len(parts) &amp;gt;= 2:&lt;br /&gt;
                authed_user = parts[1]&lt;br /&gt;
                send_line(conn, addr, &amp;quot;OK&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;PASSWORD&amp;quot; and len(parts) &amp;gt;= 2:&lt;br /&gt;
                authed_pass = parts[1]&lt;br /&gt;
                send_line(conn, addr, &amp;quot;OK&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;LOGIN&amp;quot; and len(parts) &amp;gt;= 2:&lt;br /&gt;
                upsname = parts[1]&lt;br /&gt;
                if upsname in UPS_ALIASES and authed_user == USERNAME and authed_pass == PASSWORD:&lt;br /&gt;
                    logged_in = True&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;OK&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;ERR ACCESS-DENIED&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd in (&amp;quot;MASTER&amp;quot;, &amp;quot;PRIMARY&amp;quot;) and len(parts) &amp;gt;= 2:&lt;br /&gt;
                upsname = parts[1]&lt;br /&gt;
                if logged_in and upsname in UPS_ALIASES:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;OK&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;ERR ACCESS-DENIED&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;GET&amp;quot; and len(parts) &amp;gt;= 4 and parts[1].upper() == &amp;quot;VAR&amp;quot;:&lt;br /&gt;
                ups = parts[2]&lt;br /&gt;
                var = &amp;quot; &amp;quot;.join(parts[3:])&lt;br /&gt;
&lt;br /&gt;
                if ups not in UPS_ALIASES:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;ERR UNKNOWN-UPS&amp;quot;)&lt;br /&gt;
                elif var in VARS:&lt;br /&gt;
                    resp_ups = normalize_ups_name(ups)&lt;br /&gt;
                    send_line(conn, addr, f'VAR {resp_ups} {var} &amp;quot;{VARS[var]}&amp;quot;')&lt;br /&gt;
                else:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;ERR VAR-NOT-SUPPORTED&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;LIST&amp;quot; and len(parts) &amp;gt;= 3 and parts[1].upper() == &amp;quot;VAR&amp;quot;:&lt;br /&gt;
                ups = parts[2]&lt;br /&gt;
&lt;br /&gt;
                if ups not in UPS_ALIASES:&lt;br /&gt;
                    send_line(conn, addr, &amp;quot;ERR UNKNOWN-UPS&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    resp_ups = normalize_ups_name(ups)&lt;br /&gt;
                    send_line(conn, addr, f&amp;quot;BEGIN LIST VAR {resp_ups}&amp;quot;)&lt;br /&gt;
                    for k, v in VARS.items():&lt;br /&gt;
                        send_line(conn, addr, f'VAR {resp_ups} {k} &amp;quot;{v}&amp;quot;')&lt;br /&gt;
                    send_line(conn, addr, f&amp;quot;END LIST VAR {resp_ups}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;HELP&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;OK Commands: VER NETVER PROTVER STARTTLS LIST USERNAME PASSWORD LOGIN GET LOGOUT&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            elif cmd == &amp;quot;LOGOUT&amp;quot;:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;OK Goodbye&amp;quot;)&lt;br /&gt;
                break&lt;br /&gt;
&lt;br /&gt;
            else:&lt;br /&gt;
                send_line(conn, addr, &amp;quot;ERR UNKNOWN-COMMAND&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    except Exception as e:&lt;br /&gt;
        log(f&amp;quot;[!] ERROR {addr}: {e}&amp;quot;)&lt;br /&gt;
    finally:&lt;br /&gt;
        log(f&amp;quot;[-] DISCONNECT {addr} tls={tls_started} logged_in={logged_in}&amp;quot;)&lt;br /&gt;
        try:&lt;br /&gt;
            conn.close()&lt;br /&gt;
        except Exception:&lt;br /&gt;
            pass&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    log(f&amp;quot;Starting Fake NUT DEBUG server on {HOST}:{PORT}&amp;quot;)&lt;br /&gt;
    log(f&amp;quot;Accepted UPS names: {', '.join(sorted(UPS_ALIASES))}&amp;quot;)&lt;br /&gt;
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)&lt;br /&gt;
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)&lt;br /&gt;
    s.bind((HOST, PORT))&lt;br /&gt;
    s.listen(20)&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        conn, addr = s.accept()&lt;br /&gt;
        threading.Thread(target=handle_client, args=(conn, addr), daemon=True).start()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=MacPro_6,1&amp;diff=9858</id>
		<title>MacPro 6,1</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=MacPro_6,1&amp;diff=9858"/>
		<updated>2026-03-13T22:16:43Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: = MacPro 6,1 Trashcan =  == Auto power on power loss ==  Skirta Linux:   setpci -v -s 00:1f.0 0xa4.b=0:1   Category:Apple Category:Mac OS X Category:Linux {{Template:...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= MacPro 6,1 Trashcan =&lt;br /&gt;
&lt;br /&gt;
== Auto power on power loss ==&lt;br /&gt;
&lt;br /&gt;
Skirta Linux:&lt;br /&gt;
  setpci -v -s 00:1f.0 0xa4.b=0:1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Apple]]&lt;br /&gt;
[[Category:Mac OS X]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
{{Template:Distributions}}&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9857</id>
		<title>G-RAID Studio</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9857"/>
		<updated>2026-03-13T22:10:26Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Vaizdas:Screenshot 2026-03-11 at 00.45.20.png]]&lt;br /&gt;
&lt;br /&gt;
G-Technology G-RAID Studio Thunderbolt 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prijungimas Linux'e =&lt;br /&gt;
&lt;br /&gt;
Į '''/etc/default/grub''' GRUB_CMDLINE_LINUX_DEFAULT eilutės galą arba '''/etc/kernel/cmdline''' (jeigu naudojamas [[EFI]] boot pvz ant Proxmox) reikia pridėti&lt;br /&gt;
 iommu=pt&lt;br /&gt;
&lt;br /&gt;
Pririšam thunderbolt'ą:&lt;br /&gt;
 boltctl list&lt;br /&gt;
 boltctl enroll &amp;lt;UUID&amp;gt;&lt;br /&gt;
Pvz.:&lt;br /&gt;
 boltctl enroll 00000000-0000-0018-0004-d4032e54e050&lt;br /&gt;
Žiūrim ar atsiranda devaisas:&lt;br /&gt;
 dmesg -w&lt;br /&gt;
Jeigu viskas ok ir buvo pakonfigytas ant JBOD, turėtų atsirasti diskai:&lt;br /&gt;
 lsblk&lt;br /&gt;
Jeigu neatsirado toliau žiūrime dmesg kodėl..&lt;br /&gt;
&lt;br /&gt;
== Papildoma info ==&lt;br /&gt;
&lt;br /&gt;
 c9:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (rev 11)&lt;br /&gt;
Controlleris taip pat exposina management console, kurios dar nepriveikiau...&lt;br /&gt;
 lsscsi -g&lt;br /&gt;
  [2:0:0:0]    process Marvell  Console          1.01  -          /dev/sg2 &lt;br /&gt;
 apt install sg3-utils&lt;br /&gt;
 sg_inq /dev/sg2&lt;br /&gt;
&lt;br /&gt;
Standarinės siunčiamos komandos grąžina statusą failed. Reikia tolimesnio tyrimo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Auto power on hack'as =&lt;br /&gt;
&lt;br /&gt;
Aparatas nepalaiko '''auto power on after power loss''', ar pan. konfigūracijos, todėl po elektros dingimo jį reikia įjungti rankiniu būdu kas labai nervuoja. Bet išeitis yra! Galima apgauti įjungimo mygtuką, kadangi jis yra aktyvus ir schema taip pat turi 5V išvestį, panaudojus [[esp8266]] mikrokontrolerį, galima jį įjungti automatiškai...&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8316.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Sujungimas&lt;br /&gt;
|-&lt;br /&gt;
! Board !! esp8266 !! Info&lt;br /&gt;
|-&lt;br /&gt;
| 5V || 5V || &lt;br /&gt;
|-&lt;br /&gt;
| GND || GND || &lt;br /&gt;
|-&lt;br /&gt;
| Power button || D1 || Gpio 5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Supaprastinti kodą, panaudosime [https://esphome.io esphome]..&lt;br /&gt;
&lt;br /&gt;
'''ESPHome''' konfigūracija:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
esphome:&lt;br /&gt;
  name: graid-power&lt;br /&gt;
  on_boot:&lt;br /&gt;
    priority: -100&lt;br /&gt;
    then:&lt;br /&gt;
      - delay: 1500ms&lt;br /&gt;
      - output.turn_on: pwrbtn&lt;br /&gt;
      - delay: 300ms&lt;br /&gt;
      - output.turn_off: pwrbtn&lt;br /&gt;
&lt;br /&gt;
esp8266:&lt;br /&gt;
  board: d1_mini&lt;br /&gt;
&lt;br /&gt;
logger:&lt;br /&gt;
&lt;br /&gt;
output:&lt;br /&gt;
  - platform: gpio&lt;br /&gt;
    id: pwrbtn&lt;br /&gt;
    pin:&lt;br /&gt;
      number: GPIO5&lt;br /&gt;
      mode:&lt;br /&gt;
        output: true&lt;br /&gt;
        open_drain: true&lt;br /&gt;
      inverted: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
Gal ir nekaip atrodo bet veikia !&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8351.jpg|600px]]&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8352.jpg|600px]]&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8350.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
= Reverse Engineered info =&lt;br /&gt;
&lt;br /&gt;
Standartinis softas veikia kaip web aplikacija bet turi įrankį, kuris yra pacompilintas ant i386 ir tikrai ant naujų macOS neveiks, nebent turint seną macOS relyzą su mac'u kuriame yra TB2 portai galima pajungti ir išsiaškinti. Tas įrankis naudojamas backende atlikti visus juodus darbus, kuriuos vartotojas nurodo per tą web ui:&lt;br /&gt;
 G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod: Mach-O executable i386&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Atvirkštine inžinerija išsiaiškinta šios detalės:'''&lt;br /&gt;
&lt;br /&gt;
== G-SPEED Studio CLI Notes ==&lt;br /&gt;
&lt;br /&gt;
This document explains how to use the bundled Promise/G-SPEED command line utility to:&lt;br /&gt;
&lt;br /&gt;
  * identify physical disks&lt;br /&gt;
  * list physical disks&lt;br /&gt;
  * map UI disk labels to CLI disk IDs&lt;br /&gt;
  * change disk mode between ''unconfig'' and ''passthru''&lt;br /&gt;
  * perform a few related physical-drive operations&lt;br /&gt;
&lt;br /&gt;
It is based on the software bundle in this repository, especially:&lt;br /&gt;
&lt;br /&gt;
  * ''G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod''&lt;br /&gt;
  * the web UI code that calls physical-drive APIs&lt;br /&gt;
&lt;br /&gt;
== Important terms ==&lt;br /&gt;
&lt;br /&gt;
  * '''PD ID''': Physical Drive ID used by backend/API/CLI operations.&lt;br /&gt;
  * '''pdi_FlatId''': Internal drive ID field used by the web UI data model.&lt;br /&gt;
  * '''PassThru''': What this software uses as the JBOD-like mode for a drive.&lt;br /&gt;
  * '''Unconfigured''': A drive that is not currently passed through and not in an array.&lt;br /&gt;
&lt;br /&gt;
== Important warning about numbering ==&lt;br /&gt;
&lt;br /&gt;
There are two different representations in this software:&lt;br /&gt;
&lt;br /&gt;
  * Internal/backend ID: ''pdi_FlatId''&lt;br /&gt;
  * Human-facing detail label: ''PD &amp;lt;id+1&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
That means:&lt;br /&gt;
&lt;br /&gt;
  * if the UI detail page says ''PD 1'', the backend ID may actually be ''0''&lt;br /&gt;
  * if the physical drive list shows a raw numeric ID column, that raw numeric value is the one to trust for backend and CLI work&lt;br /&gt;
&lt;br /&gt;
The web UI code confirms this:&lt;br /&gt;
&lt;br /&gt;
  * the physical drive list uses ''item.pdi_FlatId''&lt;br /&gt;
  * the detail view displays ''PD '' plus ''getId()+1''&lt;br /&gt;
&lt;br /&gt;
== Utility location ==&lt;br /&gt;
&lt;br /&gt;
Bundled CLI binary:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Short shell variable for convenience:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
CLI=&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platform note ==&lt;br /&gt;
&lt;br /&gt;
The bundled ''cli_exeMod'' in this repository is a Mach-O ''i386'' binary. On an ''arm64'' Mac it may not run directly unless the proper compatibility layer is available. The commands below document the intended usage from the bundled help text and the surrounding application code.&lt;br /&gt;
&lt;br /&gt;
== How the software changes JBOD mode ==&lt;br /&gt;
&lt;br /&gt;
The web UI does not call a special ''jbod'' command.&lt;br /&gt;
&lt;br /&gt;
It changes a physical drive's configuration state through the backend method:&lt;br /&gt;
&lt;br /&gt;
  * ''setPhyDrvSettings''&lt;br /&gt;
&lt;br /&gt;
When switching a drive into JBOD-like mode, it sets:&lt;br /&gt;
&lt;br /&gt;
  * ''pdsp_Flags = &amp;quot;PassThru&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
The equivalent CLI operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To switch back:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic discovery workflow ==&lt;br /&gt;
&lt;br /&gt;
Recommended order:&lt;br /&gt;
&lt;br /&gt;
  - List physical drives.&lt;br /&gt;
  - Identify the correct ''PD ID''.&lt;br /&gt;
  - Confirm whether the drive is already ''Unconfigured'' or ''PassThru''.&lt;br /&gt;
  - Change the mode only for the target drive.&lt;br /&gt;
  - Re-list drives to verify the new state.&lt;br /&gt;
&lt;br /&gt;
== List physical drives ==&lt;br /&gt;
&lt;br /&gt;
Basic listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explicit list action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verbose listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List all SCSI devices instead of only disks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list -l all&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What to look for in output:&lt;br /&gt;
&lt;br /&gt;
  * Physical Drive ID&lt;br /&gt;
  * model&lt;br /&gt;
  * slot/location&lt;br /&gt;
  * current status&lt;br /&gt;
  * array membership&lt;br /&gt;
  * current configuration status such as ''Unconfigured'' or ''PassThru''&lt;br /&gt;
&lt;br /&gt;
== Identify the correct PD ID ==&lt;br /&gt;
&lt;br /&gt;
=== From the web UI ===&lt;br /&gt;
&lt;br /&gt;
Use the ''Physical Drives'' page.&lt;br /&gt;
&lt;br /&gt;
The first numeric ID column comes from the raw internal field:&lt;br /&gt;
&lt;br /&gt;
  * ''pdi_FlatId''&lt;br /&gt;
&lt;br /&gt;
That is the best candidate for CLI/API work.&lt;br /&gt;
&lt;br /&gt;
Do not rely only on a detail screen label like ''PD 1'', because the detail screen may display ''id+1'' for humans.&lt;br /&gt;
&lt;br /&gt;
=== From CLI output ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bundled help text indicates the output includes physical drive information and refers to ''Physical Drive Id''.&lt;br /&gt;
&lt;br /&gt;
Once you have the printed Physical Drive ID, use that exact number with ''-p''.&lt;br /&gt;
&lt;br /&gt;
== Locate a drive physically ==&lt;br /&gt;
&lt;br /&gt;
Blink the LED for one disk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example from the bundled help:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this before changing mode if you need to confirm the exact tray/slot.&lt;br /&gt;
&lt;br /&gt;
== Change a drive to JBOD-like mode ==&lt;br /&gt;
&lt;br /&gt;
In this software, JBOD-like mode means ''PassThru''.&lt;br /&gt;
&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected use:&lt;br /&gt;
&lt;br /&gt;
  * drive should currently be ''Unconfigured''&lt;br /&gt;
  * drive should not be part of an active array&lt;br /&gt;
&lt;br /&gt;
After changing mode, verify:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change a drive back from PassThru ==&lt;br /&gt;
&lt;br /&gt;
To return a passed-through drive to ''Unconfigured'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also what the web UI does when converting a ''PassThru'' disk back to ''Unconfigured''.&lt;br /&gt;
&lt;br /&gt;
== Change drive alias ==&lt;br /&gt;
&lt;br /&gt;
The CLI help says ''alias'' can only be set on a configured drive.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;alias=MyDisk&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not assume alias changes are allowed in ''Unconfigured'' or ''PassThru'' state.&lt;br /&gt;
&lt;br /&gt;
== Other physical-drive operations ==&lt;br /&gt;
&lt;br /&gt;
Force a drive offline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a offline -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force a drive online:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a online -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear PFA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t pfa&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are riskier than listing/locating and should be used only when you are sure about the drive state.&lt;br /&gt;
&lt;br /&gt;
== Global SATA/SAS drive settings ==&lt;br /&gt;
&lt;br /&gt;
The CLI also supports global settings on SATA/SAS drives through ''phydrv -a mod'', for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -s &amp;quot;writecache=enable,rlacache=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drive-type-specific scope:&lt;br /&gt;
&lt;br /&gt;
  * ''-d sata''&lt;br /&gt;
  * ''-d sas''&lt;br /&gt;
  * ''-d all''&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -d sata -s &amp;quot;writecache=enable&amp;quot;&lt;br /&gt;
$CLI phydrv -a mod -d sas -s &amp;quot;readcache=enable,multipath=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are global settings for drives of that type, not a single-disk mode switch.&lt;br /&gt;
&lt;br /&gt;
== Arrays and PD IDs ==&lt;br /&gt;
&lt;br /&gt;
The CLI help for array creation uses PD IDs directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI array -a add -p 1,3,5~9 -l &amp;quot;raid=5,capacity=50gb,stripe=256kb&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This matters because it confirms that:&lt;br /&gt;
&lt;br /&gt;
  * the same PD ID namespace is used across physical-drive and array commands&lt;br /&gt;
  * the IDs you discover in ''phydrv'' are the IDs you would use when creating arrays&lt;br /&gt;
&lt;br /&gt;
== Safe operating procedure ==&lt;br /&gt;
&lt;br /&gt;
Before changing a disk to ''PassThru'':&lt;br /&gt;
&lt;br /&gt;
  - List all drives with ''phydrv -v''.&lt;br /&gt;
  - Record the target drive's PD ID, slot, model, and current config state.&lt;br /&gt;
  - If needed, run ''phydrv -a locate -p &amp;lt;PD_ID&amp;gt;'' to confirm the tray.&lt;br /&gt;
  - Ensure the drive is not part of an active array you care about.&lt;br /&gt;
  - Run ''phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;''.&lt;br /&gt;
  - Re-run ''phydrv -v'' and confirm the new state.&lt;br /&gt;
&lt;br /&gt;
== Common examples ==&lt;br /&gt;
&lt;br /&gt;
List drives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locate drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 to PassThru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 back to Unconfigured:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale configuration on drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p 4 -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What the web app code confirms ==&lt;br /&gt;
&lt;br /&gt;
Relevant behavior found in the application code:&lt;br /&gt;
&lt;br /&gt;
  * Physical drive IDs come from ''pdi_FlatId''.&lt;br /&gt;
  * UI detail display uses ''PD &amp;lt;id+1&amp;gt;''.&lt;br /&gt;
  * The physical-drive settings panel offers ''Unconfigured'' and ''PassThru''.&lt;br /&gt;
  * Saving those settings issues backend ''setPhyDrvSettings''.&lt;br /&gt;
  * Advanced configuration code also toggles drives through ''setPhyDrvSettings''.&lt;br /&gt;
&lt;br /&gt;
== Limitations of this note ==&lt;br /&gt;
&lt;br /&gt;
  * This document is based on bundled help text and code inspection.&lt;br /&gt;
  * The ''cli_exeMod'' binary in this repository was not executed successfully on the current ''arm64'' host during this review.&lt;br /&gt;
  * If you run this on the original supported platform, verify syntax with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI help phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -h&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Mac OS X]]&lt;br /&gt;
[[Category:ESP8266]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9856</id>
		<title>G-RAID Studio</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9856"/>
		<updated>2026-03-13T22:08:45Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Vaizdas:Screenshot 2026-03-11 at 00.45.20.png]]&lt;br /&gt;
&lt;br /&gt;
G-Technology G-RAID Studio Thunderbolt 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prijungimas Linux'e =&lt;br /&gt;
&lt;br /&gt;
Į '''/etc/default/grub''' GRUB_CMDLINE_LINUX_DEFAULT eilutės galą arba '''/etc/kernel/cmdline''' (jeigu naudojamas [[EFI]] boot pvz ant Proxmox) reikia pridėti&lt;br /&gt;
 iommu=pt&lt;br /&gt;
&lt;br /&gt;
Pririšam thunderbolt'ą:&lt;br /&gt;
 boltctl list&lt;br /&gt;
 boltctl enroll &amp;lt;UUID&amp;gt;&lt;br /&gt;
Pvz.:&lt;br /&gt;
 boltctl enroll 00000000-0000-0018-0004-d4032e54e050&lt;br /&gt;
Žiūrim ar atsiranda devaisas:&lt;br /&gt;
 dmesg -w&lt;br /&gt;
Jeigu viskas ok ir buvo pakonfigytas ant JBOD, turėtų atsirasti diskai:&lt;br /&gt;
 lsblk&lt;br /&gt;
Jeigu neatsirado toliau žiūrime dmesg kodėl..&lt;br /&gt;
&lt;br /&gt;
== Papildoma info ==&lt;br /&gt;
&lt;br /&gt;
 c9:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (rev 11)&lt;br /&gt;
Controlleris taip pat exposina management console, kurios dar nepriveikiau...&lt;br /&gt;
 lsscsi -g&lt;br /&gt;
  [2:0:0:0]    process Marvell  Console          1.01  -          /dev/sg2 &lt;br /&gt;
 apt install sg3-utils&lt;br /&gt;
 sg_inq /dev/sg2&lt;br /&gt;
&lt;br /&gt;
Standarinės siunčiamos komandos grąžina statusą failed. Reikia tolimesnio tyrimo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Auto power on hack'as =&lt;br /&gt;
&lt;br /&gt;
Aparatas nepalaiko '''auto power on after power loss''', ar pan. konfigūracijos, todėl po elektros dingimo jį reikia įjungti rankiniu būdu kas labai nervuoja. Bet išeitis yra! Galima apgauti įjungimo mygtuką, kadangi jis yra aktyvus ir schema taip pat turi 5V išvestį, panaudojus [[esp8266]] mikrokontrolerį, galima jį įjungti automatiškai...&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8316.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Sujungimas&lt;br /&gt;
|-&lt;br /&gt;
! Board !! esp8266 !! Info&lt;br /&gt;
|-&lt;br /&gt;
| 5V || 5V || &lt;br /&gt;
|-&lt;br /&gt;
| GND || GND || &lt;br /&gt;
|-&lt;br /&gt;
| Power button || D1 || Gpio 5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Supaprastinti kodą, panaudosime [https://esphome.io esphome]..&lt;br /&gt;
&lt;br /&gt;
'''ESPHome''' konfigūracija:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
esphome:&lt;br /&gt;
  name: graid-power&lt;br /&gt;
  on_boot:&lt;br /&gt;
    priority: -100&lt;br /&gt;
    then:&lt;br /&gt;
      - delay: 1500ms&lt;br /&gt;
      - output.turn_on: pwrbtn&lt;br /&gt;
      - delay: 300ms&lt;br /&gt;
      - output.turn_off: pwrbtn&lt;br /&gt;
&lt;br /&gt;
esp8266:&lt;br /&gt;
  board: d1_mini&lt;br /&gt;
&lt;br /&gt;
logger:&lt;br /&gt;
&lt;br /&gt;
output:&lt;br /&gt;
  - platform: gpio&lt;br /&gt;
    id: pwrbtn&lt;br /&gt;
    pin:&lt;br /&gt;
      number: GPIO5&lt;br /&gt;
      mode:&lt;br /&gt;
        output: true&lt;br /&gt;
        open_drain: true&lt;br /&gt;
      inverted: true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
Gal ir nekaip atrodo bet veikia !&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8351.jpg|600px]]&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8352.jpg|600px]]&lt;br /&gt;
[[Vaizdas:Graid-auto-power-hack-IMG 8350.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
= Reverse Engineered info =&lt;br /&gt;
&lt;br /&gt;
Standartinis softas veikia kaip web aplikacija bet turi įrankį, kuris yra pacompilintas ant i386 ir tikrai ant naujų macOS neveiks, nebent turint seną macOS relyzą su mac'u kuriame yra TB2 portai galima pajungti ir išsiaškinti. Tas įrankis naudojamas backende atlikti visus juodus darbus, kuriuos vartotojas nurodo per tą web ui:&lt;br /&gt;
 G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod: Mach-O executable i386&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Atvirkštine inžinerija išsiaiškinta šios detalės:'''&lt;br /&gt;
&lt;br /&gt;
== G-SPEED Studio CLI Notes ==&lt;br /&gt;
&lt;br /&gt;
This document explains how to use the bundled Promise/G-SPEED command line utility to:&lt;br /&gt;
&lt;br /&gt;
  * identify physical disks&lt;br /&gt;
  * list physical disks&lt;br /&gt;
  * map UI disk labels to CLI disk IDs&lt;br /&gt;
  * change disk mode between ''unconfig'' and ''passthru''&lt;br /&gt;
  * perform a few related physical-drive operations&lt;br /&gt;
&lt;br /&gt;
It is based on the software bundle in this repository, especially:&lt;br /&gt;
&lt;br /&gt;
  * ''G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod''&lt;br /&gt;
  * the web UI code that calls physical-drive APIs&lt;br /&gt;
&lt;br /&gt;
== Important terms ==&lt;br /&gt;
&lt;br /&gt;
  * '''PD ID''': Physical Drive ID used by backend/API/CLI operations.&lt;br /&gt;
  * '''pdi_FlatId''': Internal drive ID field used by the web UI data model.&lt;br /&gt;
  * '''PassThru''': What this software uses as the JBOD-like mode for a drive.&lt;br /&gt;
  * '''Unconfigured''': A drive that is not currently passed through and not in an array.&lt;br /&gt;
&lt;br /&gt;
== Important warning about numbering ==&lt;br /&gt;
&lt;br /&gt;
There are two different representations in this software:&lt;br /&gt;
&lt;br /&gt;
  * Internal/backend ID: ''pdi_FlatId''&lt;br /&gt;
  * Human-facing detail label: ''PD &amp;lt;id+1&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
That means:&lt;br /&gt;
&lt;br /&gt;
  * if the UI detail page says ''PD 1'', the backend ID may actually be ''0''&lt;br /&gt;
  * if the physical drive list shows a raw numeric ID column, that raw numeric value is the one to trust for backend and CLI work&lt;br /&gt;
&lt;br /&gt;
The web UI code confirms this:&lt;br /&gt;
&lt;br /&gt;
  * the physical drive list uses ''item.pdi_FlatId''&lt;br /&gt;
  * the detail view displays ''PD '' plus ''getId()+1''&lt;br /&gt;
&lt;br /&gt;
== Utility location ==&lt;br /&gt;
&lt;br /&gt;
Bundled CLI binary:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Short shell variable for convenience:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
CLI=&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platform note ==&lt;br /&gt;
&lt;br /&gt;
The bundled ''cli_exeMod'' in this repository is a Mach-O ''i386'' binary. On an ''arm64'' Mac it may not run directly unless the proper compatibility layer is available. The commands below document the intended usage from the bundled help text and the surrounding application code.&lt;br /&gt;
&lt;br /&gt;
== How the software changes JBOD mode ==&lt;br /&gt;
&lt;br /&gt;
The web UI does not call a special ''jbod'' command.&lt;br /&gt;
&lt;br /&gt;
It changes a physical drive's configuration state through the backend method:&lt;br /&gt;
&lt;br /&gt;
  * ''setPhyDrvSettings''&lt;br /&gt;
&lt;br /&gt;
When switching a drive into JBOD-like mode, it sets:&lt;br /&gt;
&lt;br /&gt;
  * ''pdsp_Flags = &amp;quot;PassThru&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
The equivalent CLI operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To switch back:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic discovery workflow ==&lt;br /&gt;
&lt;br /&gt;
Recommended order:&lt;br /&gt;
&lt;br /&gt;
  - List physical drives.&lt;br /&gt;
  - Identify the correct ''PD ID''.&lt;br /&gt;
  - Confirm whether the drive is already ''Unconfigured'' or ''PassThru''.&lt;br /&gt;
  - Change the mode only for the target drive.&lt;br /&gt;
  - Re-list drives to verify the new state.&lt;br /&gt;
&lt;br /&gt;
== List physical drives ==&lt;br /&gt;
&lt;br /&gt;
Basic listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explicit list action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verbose listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List all SCSI devices instead of only disks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list -l all&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What to look for in output:&lt;br /&gt;
&lt;br /&gt;
  * Physical Drive ID&lt;br /&gt;
  * model&lt;br /&gt;
  * slot/location&lt;br /&gt;
  * current status&lt;br /&gt;
  * array membership&lt;br /&gt;
  * current configuration status such as ''Unconfigured'' or ''PassThru''&lt;br /&gt;
&lt;br /&gt;
== Identify the correct PD ID ==&lt;br /&gt;
&lt;br /&gt;
=== From the web UI ===&lt;br /&gt;
&lt;br /&gt;
Use the ''Physical Drives'' page.&lt;br /&gt;
&lt;br /&gt;
The first numeric ID column comes from the raw internal field:&lt;br /&gt;
&lt;br /&gt;
  * ''pdi_FlatId''&lt;br /&gt;
&lt;br /&gt;
That is the best candidate for CLI/API work.&lt;br /&gt;
&lt;br /&gt;
Do not rely only on a detail screen label like ''PD 1'', because the detail screen may display ''id+1'' for humans.&lt;br /&gt;
&lt;br /&gt;
=== From CLI output ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bundled help text indicates the output includes physical drive information and refers to ''Physical Drive Id''.&lt;br /&gt;
&lt;br /&gt;
Once you have the printed Physical Drive ID, use that exact number with ''-p''.&lt;br /&gt;
&lt;br /&gt;
== Locate a drive physically ==&lt;br /&gt;
&lt;br /&gt;
Blink the LED for one disk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example from the bundled help:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this before changing mode if you need to confirm the exact tray/slot.&lt;br /&gt;
&lt;br /&gt;
== Change a drive to JBOD-like mode ==&lt;br /&gt;
&lt;br /&gt;
In this software, JBOD-like mode means ''PassThru''.&lt;br /&gt;
&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected use:&lt;br /&gt;
&lt;br /&gt;
  * drive should currently be ''Unconfigured''&lt;br /&gt;
  * drive should not be part of an active array&lt;br /&gt;
&lt;br /&gt;
After changing mode, verify:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change a drive back from PassThru ==&lt;br /&gt;
&lt;br /&gt;
To return a passed-through drive to ''Unconfigured'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also what the web UI does when converting a ''PassThru'' disk back to ''Unconfigured''.&lt;br /&gt;
&lt;br /&gt;
== Change drive alias ==&lt;br /&gt;
&lt;br /&gt;
The CLI help says ''alias'' can only be set on a configured drive.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;alias=MyDisk&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not assume alias changes are allowed in ''Unconfigured'' or ''PassThru'' state.&lt;br /&gt;
&lt;br /&gt;
== Other physical-drive operations ==&lt;br /&gt;
&lt;br /&gt;
Force a drive offline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a offline -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force a drive online:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a online -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear PFA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t pfa&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are riskier than listing/locating and should be used only when you are sure about the drive state.&lt;br /&gt;
&lt;br /&gt;
== Global SATA/SAS drive settings ==&lt;br /&gt;
&lt;br /&gt;
The CLI also supports global settings on SATA/SAS drives through ''phydrv -a mod'', for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -s &amp;quot;writecache=enable,rlacache=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drive-type-specific scope:&lt;br /&gt;
&lt;br /&gt;
  * ''-d sata''&lt;br /&gt;
  * ''-d sas''&lt;br /&gt;
  * ''-d all''&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -d sata -s &amp;quot;writecache=enable&amp;quot;&lt;br /&gt;
$CLI phydrv -a mod -d sas -s &amp;quot;readcache=enable,multipath=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are global settings for drives of that type, not a single-disk mode switch.&lt;br /&gt;
&lt;br /&gt;
== Arrays and PD IDs ==&lt;br /&gt;
&lt;br /&gt;
The CLI help for array creation uses PD IDs directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI array -a add -p 1,3,5~9 -l &amp;quot;raid=5,capacity=50gb,stripe=256kb&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This matters because it confirms that:&lt;br /&gt;
&lt;br /&gt;
  * the same PD ID namespace is used across physical-drive and array commands&lt;br /&gt;
  * the IDs you discover in ''phydrv'' are the IDs you would use when creating arrays&lt;br /&gt;
&lt;br /&gt;
== Safe operating procedure ==&lt;br /&gt;
&lt;br /&gt;
Before changing a disk to ''PassThru'':&lt;br /&gt;
&lt;br /&gt;
  - List all drives with ''phydrv -v''.&lt;br /&gt;
  - Record the target drive's PD ID, slot, model, and current config state.&lt;br /&gt;
  - If needed, run ''phydrv -a locate -p &amp;lt;PD_ID&amp;gt;'' to confirm the tray.&lt;br /&gt;
  - Ensure the drive is not part of an active array you care about.&lt;br /&gt;
  - Run ''phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;''.&lt;br /&gt;
  - Re-run ''phydrv -v'' and confirm the new state.&lt;br /&gt;
&lt;br /&gt;
== Common examples ==&lt;br /&gt;
&lt;br /&gt;
List drives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locate drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 to PassThru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 back to Unconfigured:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale configuration on drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p 4 -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What the web app code confirms ==&lt;br /&gt;
&lt;br /&gt;
Relevant behavior found in the application code:&lt;br /&gt;
&lt;br /&gt;
  * Physical drive IDs come from ''pdi_FlatId''.&lt;br /&gt;
  * UI detail display uses ''PD &amp;lt;id+1&amp;gt;''.&lt;br /&gt;
  * The physical-drive settings panel offers ''Unconfigured'' and ''PassThru''.&lt;br /&gt;
  * Saving those settings issues backend ''setPhyDrvSettings''.&lt;br /&gt;
  * Advanced configuration code also toggles drives through ''setPhyDrvSettings''.&lt;br /&gt;
&lt;br /&gt;
== Limitations of this note ==&lt;br /&gt;
&lt;br /&gt;
  * This document is based on bundled help text and code inspection.&lt;br /&gt;
  * The ''cli_exeMod'' binary in this repository was not executed successfully on the current ''arm64'' host during this review.&lt;br /&gt;
  * If you run this on the original supported platform, verify syntax with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI help phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -h&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Mac OS X]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8350.jpg&amp;diff=9855</id>
		<title>Vaizdas:Graid-auto-power-hack-IMG 8350.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8350.jpg&amp;diff=9855"/>
		<updated>2026-03-13T22:02:40Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8352.jpg&amp;diff=9854</id>
		<title>Vaizdas:Graid-auto-power-hack-IMG 8352.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8352.jpg&amp;diff=9854"/>
		<updated>2026-03-13T22:02:18Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8351.jpg&amp;diff=9853</id>
		<title>Vaizdas:Graid-auto-power-hack-IMG 8351.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8351.jpg&amp;diff=9853"/>
		<updated>2026-03-13T22:01:50Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8316.jpg&amp;diff=9852</id>
		<title>Vaizdas:Graid-auto-power-hack-IMG 8316.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Graid-auto-power-hack-IMG_8316.jpg&amp;diff=9852"/>
		<updated>2026-03-13T22:01:10Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9851</id>
		<title>G-RAID Studio</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9851"/>
		<updated>2026-03-10T22:48:04Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: /* Prijungimas Linux'e */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Vaizdas:Screenshot 2026-03-11 at 00.45.20.png]]&lt;br /&gt;
&lt;br /&gt;
G-Technology G-RAID Studio Thunderbolt 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prijungimas Linux'e =&lt;br /&gt;
&lt;br /&gt;
Į '''/etc/default/grub''' GRUB_CMDLINE_LINUX_DEFAULT eilutės galą arba '''/etc/kernel/cmdline''' (jeigu naudojamas [[EFI]] boot pvz ant Proxmox) reikia pridėti&lt;br /&gt;
 iommu=pt&lt;br /&gt;
&lt;br /&gt;
Pririšam thunderbolt'ą:&lt;br /&gt;
 boltctl list&lt;br /&gt;
 boltctl enroll &amp;lt;UUID&amp;gt;&lt;br /&gt;
Pvz.:&lt;br /&gt;
 boltctl enroll 00000000-0000-0018-0004-d4032e54e050&lt;br /&gt;
Žiūrim ar atsiranda devaisas:&lt;br /&gt;
 dmesg -w&lt;br /&gt;
Jeigu viskas ok ir buvo pakonfigytas ant JBOD, turėtų atsirasti diskai:&lt;br /&gt;
 lsblk&lt;br /&gt;
Jeigu neatsirado toliau žiūrime dmesg kodėl..&lt;br /&gt;
&lt;br /&gt;
== Papildoma info ==&lt;br /&gt;
&lt;br /&gt;
 c9:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (rev 11)&lt;br /&gt;
Controlleris taip pat exposina management console, kurios dar nepriveikiau...&lt;br /&gt;
 lsscsi -g&lt;br /&gt;
  [2:0:0:0]    process Marvell  Console          1.01  -          /dev/sg2 &lt;br /&gt;
 apt install sg3-utils&lt;br /&gt;
 sg_inq /dev/sg2&lt;br /&gt;
&lt;br /&gt;
Standarinės siunčiamos komandos grąžina statusą failed. Reikia tolimesnio tyrimo.&lt;br /&gt;
&lt;br /&gt;
= Reverse Engineered info =&lt;br /&gt;
&lt;br /&gt;
Standartinis softas veikia kaip web aplikacija bet turi įrankį, kuris yra pacompilintas ant i386 ir tikrai ant naujų macOS neveiks, nebent turint seną macOS relyzą su mac'u kuriame yra TB2 portai galima pajungti ir išsiaškinti. Tas įrankis naudojamas backende atlikti visus juodus darbus, kuriuos vartotojas nurodo per tą web ui:&lt;br /&gt;
 G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod: Mach-O executable i386&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Atvirkštine inžinerija išsiaiškinta šios detalės:'''&lt;br /&gt;
&lt;br /&gt;
== G-SPEED Studio CLI Notes ==&lt;br /&gt;
&lt;br /&gt;
This document explains how to use the bundled Promise/G-SPEED command line utility to:&lt;br /&gt;
&lt;br /&gt;
  * identify physical disks&lt;br /&gt;
  * list physical disks&lt;br /&gt;
  * map UI disk labels to CLI disk IDs&lt;br /&gt;
  * change disk mode between ''unconfig'' and ''passthru''&lt;br /&gt;
  * perform a few related physical-drive operations&lt;br /&gt;
&lt;br /&gt;
It is based on the software bundle in this repository, especially:&lt;br /&gt;
&lt;br /&gt;
  * ''G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod''&lt;br /&gt;
  * the web UI code that calls physical-drive APIs&lt;br /&gt;
&lt;br /&gt;
== Important terms ==&lt;br /&gt;
&lt;br /&gt;
  * '''PD ID''': Physical Drive ID used by backend/API/CLI operations.&lt;br /&gt;
  * '''pdi_FlatId''': Internal drive ID field used by the web UI data model.&lt;br /&gt;
  * '''PassThru''': What this software uses as the JBOD-like mode for a drive.&lt;br /&gt;
  * '''Unconfigured''': A drive that is not currently passed through and not in an array.&lt;br /&gt;
&lt;br /&gt;
== Important warning about numbering ==&lt;br /&gt;
&lt;br /&gt;
There are two different representations in this software:&lt;br /&gt;
&lt;br /&gt;
  * Internal/backend ID: ''pdi_FlatId''&lt;br /&gt;
  * Human-facing detail label: ''PD &amp;lt;id+1&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
That means:&lt;br /&gt;
&lt;br /&gt;
  * if the UI detail page says ''PD 1'', the backend ID may actually be ''0''&lt;br /&gt;
  * if the physical drive list shows a raw numeric ID column, that raw numeric value is the one to trust for backend and CLI work&lt;br /&gt;
&lt;br /&gt;
The web UI code confirms this:&lt;br /&gt;
&lt;br /&gt;
  * the physical drive list uses ''item.pdi_FlatId''&lt;br /&gt;
  * the detail view displays ''PD '' plus ''getId()+1''&lt;br /&gt;
&lt;br /&gt;
== Utility location ==&lt;br /&gt;
&lt;br /&gt;
Bundled CLI binary:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Short shell variable for convenience:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
CLI=&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platform note ==&lt;br /&gt;
&lt;br /&gt;
The bundled ''cli_exeMod'' in this repository is a Mach-O ''i386'' binary. On an ''arm64'' Mac it may not run directly unless the proper compatibility layer is available. The commands below document the intended usage from the bundled help text and the surrounding application code.&lt;br /&gt;
&lt;br /&gt;
== How the software changes JBOD mode ==&lt;br /&gt;
&lt;br /&gt;
The web UI does not call a special ''jbod'' command.&lt;br /&gt;
&lt;br /&gt;
It changes a physical drive's configuration state through the backend method:&lt;br /&gt;
&lt;br /&gt;
  * ''setPhyDrvSettings''&lt;br /&gt;
&lt;br /&gt;
When switching a drive into JBOD-like mode, it sets:&lt;br /&gt;
&lt;br /&gt;
  * ''pdsp_Flags = &amp;quot;PassThru&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
The equivalent CLI operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To switch back:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic discovery workflow ==&lt;br /&gt;
&lt;br /&gt;
Recommended order:&lt;br /&gt;
&lt;br /&gt;
  - List physical drives.&lt;br /&gt;
  - Identify the correct ''PD ID''.&lt;br /&gt;
  - Confirm whether the drive is already ''Unconfigured'' or ''PassThru''.&lt;br /&gt;
  - Change the mode only for the target drive.&lt;br /&gt;
  - Re-list drives to verify the new state.&lt;br /&gt;
&lt;br /&gt;
== List physical drives ==&lt;br /&gt;
&lt;br /&gt;
Basic listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explicit list action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verbose listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List all SCSI devices instead of only disks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list -l all&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What to look for in output:&lt;br /&gt;
&lt;br /&gt;
  * Physical Drive ID&lt;br /&gt;
  * model&lt;br /&gt;
  * slot/location&lt;br /&gt;
  * current status&lt;br /&gt;
  * array membership&lt;br /&gt;
  * current configuration status such as ''Unconfigured'' or ''PassThru''&lt;br /&gt;
&lt;br /&gt;
== Identify the correct PD ID ==&lt;br /&gt;
&lt;br /&gt;
=== From the web UI ===&lt;br /&gt;
&lt;br /&gt;
Use the ''Physical Drives'' page.&lt;br /&gt;
&lt;br /&gt;
The first numeric ID column comes from the raw internal field:&lt;br /&gt;
&lt;br /&gt;
  * ''pdi_FlatId''&lt;br /&gt;
&lt;br /&gt;
That is the best candidate for CLI/API work.&lt;br /&gt;
&lt;br /&gt;
Do not rely only on a detail screen label like ''PD 1'', because the detail screen may display ''id+1'' for humans.&lt;br /&gt;
&lt;br /&gt;
=== From CLI output ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bundled help text indicates the output includes physical drive information and refers to ''Physical Drive Id''.&lt;br /&gt;
&lt;br /&gt;
Once you have the printed Physical Drive ID, use that exact number with ''-p''.&lt;br /&gt;
&lt;br /&gt;
== Locate a drive physically ==&lt;br /&gt;
&lt;br /&gt;
Blink the LED for one disk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example from the bundled help:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this before changing mode if you need to confirm the exact tray/slot.&lt;br /&gt;
&lt;br /&gt;
== Change a drive to JBOD-like mode ==&lt;br /&gt;
&lt;br /&gt;
In this software, JBOD-like mode means ''PassThru''.&lt;br /&gt;
&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected use:&lt;br /&gt;
&lt;br /&gt;
  * drive should currently be ''Unconfigured''&lt;br /&gt;
  * drive should not be part of an active array&lt;br /&gt;
&lt;br /&gt;
After changing mode, verify:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change a drive back from PassThru ==&lt;br /&gt;
&lt;br /&gt;
To return a passed-through drive to ''Unconfigured'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also what the web UI does when converting a ''PassThru'' disk back to ''Unconfigured''.&lt;br /&gt;
&lt;br /&gt;
== Change drive alias ==&lt;br /&gt;
&lt;br /&gt;
The CLI help says ''alias'' can only be set on a configured drive.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;alias=MyDisk&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not assume alias changes are allowed in ''Unconfigured'' or ''PassThru'' state.&lt;br /&gt;
&lt;br /&gt;
== Other physical-drive operations ==&lt;br /&gt;
&lt;br /&gt;
Force a drive offline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a offline -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force a drive online:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a online -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear PFA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t pfa&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are riskier than listing/locating and should be used only when you are sure about the drive state.&lt;br /&gt;
&lt;br /&gt;
== Global SATA/SAS drive settings ==&lt;br /&gt;
&lt;br /&gt;
The CLI also supports global settings on SATA/SAS drives through ''phydrv -a mod'', for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -s &amp;quot;writecache=enable,rlacache=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drive-type-specific scope:&lt;br /&gt;
&lt;br /&gt;
  * ''-d sata''&lt;br /&gt;
  * ''-d sas''&lt;br /&gt;
  * ''-d all''&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -d sata -s &amp;quot;writecache=enable&amp;quot;&lt;br /&gt;
$CLI phydrv -a mod -d sas -s &amp;quot;readcache=enable,multipath=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are global settings for drives of that type, not a single-disk mode switch.&lt;br /&gt;
&lt;br /&gt;
== Arrays and PD IDs ==&lt;br /&gt;
&lt;br /&gt;
The CLI help for array creation uses PD IDs directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI array -a add -p 1,3,5~9 -l &amp;quot;raid=5,capacity=50gb,stripe=256kb&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This matters because it confirms that:&lt;br /&gt;
&lt;br /&gt;
  * the same PD ID namespace is used across physical-drive and array commands&lt;br /&gt;
  * the IDs you discover in ''phydrv'' are the IDs you would use when creating arrays&lt;br /&gt;
&lt;br /&gt;
== Safe operating procedure ==&lt;br /&gt;
&lt;br /&gt;
Before changing a disk to ''PassThru'':&lt;br /&gt;
&lt;br /&gt;
  - List all drives with ''phydrv -v''.&lt;br /&gt;
  - Record the target drive's PD ID, slot, model, and current config state.&lt;br /&gt;
  - If needed, run ''phydrv -a locate -p &amp;lt;PD_ID&amp;gt;'' to confirm the tray.&lt;br /&gt;
  - Ensure the drive is not part of an active array you care about.&lt;br /&gt;
  - Run ''phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;''.&lt;br /&gt;
  - Re-run ''phydrv -v'' and confirm the new state.&lt;br /&gt;
&lt;br /&gt;
== Common examples ==&lt;br /&gt;
&lt;br /&gt;
List drives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locate drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 to PassThru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 back to Unconfigured:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale configuration on drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p 4 -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What the web app code confirms ==&lt;br /&gt;
&lt;br /&gt;
Relevant behavior found in the application code:&lt;br /&gt;
&lt;br /&gt;
  * Physical drive IDs come from ''pdi_FlatId''.&lt;br /&gt;
  * UI detail display uses ''PD &amp;lt;id+1&amp;gt;''.&lt;br /&gt;
  * The physical-drive settings panel offers ''Unconfigured'' and ''PassThru''.&lt;br /&gt;
  * Saving those settings issues backend ''setPhyDrvSettings''.&lt;br /&gt;
  * Advanced configuration code also toggles drives through ''setPhyDrvSettings''.&lt;br /&gt;
&lt;br /&gt;
== Limitations of this note ==&lt;br /&gt;
&lt;br /&gt;
  * This document is based on bundled help text and code inspection.&lt;br /&gt;
  * The ''cli_exeMod'' binary in this repository was not executed successfully on the current ''arm64'' host during this review.&lt;br /&gt;
  * If you run this on the original supported platform, verify syntax with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI help phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -h&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Mac OS X]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9850</id>
		<title>G-RAID Studio</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=G-RAID_Studio&amp;diff=9850"/>
		<updated>2026-03-10T22:46:42Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: Vaizdas:Screenshot 2026-03-11 at 00.45.20.png  G-Technology G-RAID Studio Thunderbolt 2   = Prijungimas Linux'e =  Į /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT arba /etc/k...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Vaizdas:Screenshot 2026-03-11 at 00.45.20.png]]&lt;br /&gt;
&lt;br /&gt;
G-Technology G-RAID Studio Thunderbolt 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prijungimas Linux'e =&lt;br /&gt;
&lt;br /&gt;
Į /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT arba /etc/kernel/cmdline rekia pridėti&lt;br /&gt;
 iommu=pt&lt;br /&gt;
&lt;br /&gt;
Pririšam thunderbolt'ą:&lt;br /&gt;
 boltctl list&lt;br /&gt;
 boltctl enroll &amp;lt;UUID&amp;gt;&lt;br /&gt;
Pvz.:&lt;br /&gt;
 boltctl enroll 00000000-0000-0018-0004-d4032e54e050&lt;br /&gt;
Žiūrim ar atsiranda devaisas:&lt;br /&gt;
 dmesg -w&lt;br /&gt;
Jeigu viskas ok ir buvo pakonfigytas ant JBOD, turėtų atsirasti diskai:&lt;br /&gt;
 lsblk&lt;br /&gt;
Jeigu neatsirado toliau žiūrime dmesg kodėl..&lt;br /&gt;
&lt;br /&gt;
== Papildoma info ==&lt;br /&gt;
&lt;br /&gt;
 c9:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller (rev 11)&lt;br /&gt;
Controlleris taip pat exposina management console, kurios dar nepriveikiau...&lt;br /&gt;
 lsscsi -g&lt;br /&gt;
  [2:0:0:0]    process Marvell  Console          1.01  -          /dev/sg2 &lt;br /&gt;
 apt install sg3-utils&lt;br /&gt;
 sg_inq /dev/sg2&lt;br /&gt;
&lt;br /&gt;
Standarinės siunčiamos komandos grąžina statusą failed. Reikia tolimesnio tyrimo.&lt;br /&gt;
&lt;br /&gt;
= Reverse Engineered info =&lt;br /&gt;
&lt;br /&gt;
Standartinis softas veikia kaip web aplikacija bet turi įrankį, kuris yra pacompilintas ant i386 ir tikrai ant naujų macOS neveiks, nebent turint seną macOS relyzą su mac'u kuriame yra TB2 portai galima pajungti ir išsiaškinti. Tas įrankis naudojamas backende atlikti visus juodus darbus, kuriuos vartotojas nurodo per tą web ui:&lt;br /&gt;
 G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod: Mach-O executable i386&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Atvirkštine inžinerija išsiaiškinta šios detalės:'''&lt;br /&gt;
&lt;br /&gt;
== G-SPEED Studio CLI Notes ==&lt;br /&gt;
&lt;br /&gt;
This document explains how to use the bundled Promise/G-SPEED command line utility to:&lt;br /&gt;
&lt;br /&gt;
  * identify physical disks&lt;br /&gt;
  * list physical disks&lt;br /&gt;
  * map UI disk labels to CLI disk IDs&lt;br /&gt;
  * change disk mode between ''unconfig'' and ''passthru''&lt;br /&gt;
  * perform a few related physical-drive operations&lt;br /&gt;
&lt;br /&gt;
It is based on the software bundle in this repository, especially:&lt;br /&gt;
&lt;br /&gt;
  * ''G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod''&lt;br /&gt;
  * the web UI code that calls physical-drive APIs&lt;br /&gt;
&lt;br /&gt;
== Important terms ==&lt;br /&gt;
&lt;br /&gt;
  * '''PD ID''': Physical Drive ID used by backend/API/CLI operations.&lt;br /&gt;
  * '''pdi_FlatId''': Internal drive ID field used by the web UI data model.&lt;br /&gt;
  * '''PassThru''': What this software uses as the JBOD-like mode for a drive.&lt;br /&gt;
  * '''Unconfigured''': A drive that is not currently passed through and not in an array.&lt;br /&gt;
&lt;br /&gt;
== Important warning about numbering ==&lt;br /&gt;
&lt;br /&gt;
There are two different representations in this software:&lt;br /&gt;
&lt;br /&gt;
  * Internal/backend ID: ''pdi_FlatId''&lt;br /&gt;
  * Human-facing detail label: ''PD &amp;lt;id+1&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
That means:&lt;br /&gt;
&lt;br /&gt;
  * if the UI detail page says ''PD 1'', the backend ID may actually be ''0''&lt;br /&gt;
  * if the physical drive list shows a raw numeric ID column, that raw numeric value is the one to trust for backend and CLI work&lt;br /&gt;
&lt;br /&gt;
The web UI code confirms this:&lt;br /&gt;
&lt;br /&gt;
  * the physical drive list uses ''item.pdi_FlatId''&lt;br /&gt;
  * the detail view displays ''PD '' plus ''getId()+1''&lt;br /&gt;
&lt;br /&gt;
== Utility location ==&lt;br /&gt;
&lt;br /&gt;
Bundled CLI binary:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Short shell variable for convenience:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
CLI=&amp;quot;/Users/devnull/Projects/G-Drive/G-SPEED Studio Software Utility.app/Contents/Resources/XMLBase/cli_exeMod&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platform note ==&lt;br /&gt;
&lt;br /&gt;
The bundled ''cli_exeMod'' in this repository is a Mach-O ''i386'' binary. On an ''arm64'' Mac it may not run directly unless the proper compatibility layer is available. The commands below document the intended usage from the bundled help text and the surrounding application code.&lt;br /&gt;
&lt;br /&gt;
== How the software changes JBOD mode ==&lt;br /&gt;
&lt;br /&gt;
The web UI does not call a special ''jbod'' command.&lt;br /&gt;
&lt;br /&gt;
It changes a physical drive's configuration state through the backend method:&lt;br /&gt;
&lt;br /&gt;
  * ''setPhyDrvSettings''&lt;br /&gt;
&lt;br /&gt;
When switching a drive into JBOD-like mode, it sets:&lt;br /&gt;
&lt;br /&gt;
  * ''pdsp_Flags = &amp;quot;PassThru&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
The equivalent CLI operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To switch back:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Basic discovery workflow ==&lt;br /&gt;
&lt;br /&gt;
Recommended order:&lt;br /&gt;
&lt;br /&gt;
  - List physical drives.&lt;br /&gt;
  - Identify the correct ''PD ID''.&lt;br /&gt;
  - Confirm whether the drive is already ''Unconfigured'' or ''PassThru''.&lt;br /&gt;
  - Change the mode only for the target drive.&lt;br /&gt;
  - Re-list drives to verify the new state.&lt;br /&gt;
&lt;br /&gt;
== List physical drives ==&lt;br /&gt;
&lt;br /&gt;
Basic listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explicit list action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verbose listing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
List all SCSI devices instead of only disks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a list -l all&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What to look for in output:&lt;br /&gt;
&lt;br /&gt;
  * Physical Drive ID&lt;br /&gt;
  * model&lt;br /&gt;
  * slot/location&lt;br /&gt;
  * current status&lt;br /&gt;
  * array membership&lt;br /&gt;
  * current configuration status such as ''Unconfigured'' or ''PassThru''&lt;br /&gt;
&lt;br /&gt;
== Identify the correct PD ID ==&lt;br /&gt;
&lt;br /&gt;
=== From the web UI ===&lt;br /&gt;
&lt;br /&gt;
Use the ''Physical Drives'' page.&lt;br /&gt;
&lt;br /&gt;
The first numeric ID column comes from the raw internal field:&lt;br /&gt;
&lt;br /&gt;
  * ''pdi_FlatId''&lt;br /&gt;
&lt;br /&gt;
That is the best candidate for CLI/API work.&lt;br /&gt;
&lt;br /&gt;
Do not rely only on a detail screen label like ''PD 1'', because the detail screen may display ''id+1'' for humans.&lt;br /&gt;
&lt;br /&gt;
=== From CLI output ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bundled help text indicates the output includes physical drive information and refers to ''Physical Drive Id''.&lt;br /&gt;
&lt;br /&gt;
Once you have the printed Physical Drive ID, use that exact number with ''-p''.&lt;br /&gt;
&lt;br /&gt;
== Locate a drive physically ==&lt;br /&gt;
&lt;br /&gt;
Blink the LED for one disk:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example from the bundled help:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 9&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this before changing mode if you need to confirm the exact tray/slot.&lt;br /&gt;
&lt;br /&gt;
== Change a drive to JBOD-like mode ==&lt;br /&gt;
&lt;br /&gt;
In this software, JBOD-like mode means ''PassThru''.&lt;br /&gt;
&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expected use:&lt;br /&gt;
&lt;br /&gt;
  * drive should currently be ''Unconfigured''&lt;br /&gt;
  * drive should not be part of an active array&lt;br /&gt;
&lt;br /&gt;
After changing mode, verify:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Change a drive back from PassThru ==&lt;br /&gt;
&lt;br /&gt;
To return a passed-through drive to ''Unconfigured'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 9 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is also what the web UI does when converting a ''PassThru'' disk back to ''Unconfigured''.&lt;br /&gt;
&lt;br /&gt;
== Change drive alias ==&lt;br /&gt;
&lt;br /&gt;
The CLI help says ''alias'' can only be set on a configured drive.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;alias=MyDisk&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not assume alias changes are allowed in ''Unconfigured'' or ''PassThru'' state.&lt;br /&gt;
&lt;br /&gt;
== Other physical-drive operations ==&lt;br /&gt;
&lt;br /&gt;
Force a drive offline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a offline -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Force a drive online:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a online -p &amp;lt;PD_ID&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear PFA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t pfa&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale config:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p &amp;lt;PD_ID&amp;gt; -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are riskier than listing/locating and should be used only when you are sure about the drive state.&lt;br /&gt;
&lt;br /&gt;
== Global SATA/SAS drive settings ==&lt;br /&gt;
&lt;br /&gt;
The CLI also supports global settings on SATA/SAS drives through ''phydrv -a mod'', for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -s &amp;quot;writecache=enable,rlacache=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drive-type-specific scope:&lt;br /&gt;
&lt;br /&gt;
  * ''-d sata''&lt;br /&gt;
  * ''-d sas''&lt;br /&gt;
  * ''-d all''&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -d sata -s &amp;quot;writecache=enable&amp;quot;&lt;br /&gt;
$CLI phydrv -a mod -d sas -s &amp;quot;readcache=enable,multipath=enable&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These are global settings for drives of that type, not a single-disk mode switch.&lt;br /&gt;
&lt;br /&gt;
== Arrays and PD IDs ==&lt;br /&gt;
&lt;br /&gt;
The CLI help for array creation uses PD IDs directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI array -a add -p 1,3,5~9 -l &amp;quot;raid=5,capacity=50gb,stripe=256kb&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This matters because it confirms that:&lt;br /&gt;
&lt;br /&gt;
  * the same PD ID namespace is used across physical-drive and array commands&lt;br /&gt;
  * the IDs you discover in ''phydrv'' are the IDs you would use when creating arrays&lt;br /&gt;
&lt;br /&gt;
== Safe operating procedure ==&lt;br /&gt;
&lt;br /&gt;
Before changing a disk to ''PassThru'':&lt;br /&gt;
&lt;br /&gt;
  - List all drives with ''phydrv -v''.&lt;br /&gt;
  - Record the target drive's PD ID, slot, model, and current config state.&lt;br /&gt;
  - If needed, run ''phydrv -a locate -p &amp;lt;PD_ID&amp;gt;'' to confirm the tray.&lt;br /&gt;
  - Ensure the drive is not part of an active array you care about.&lt;br /&gt;
  - Run ''phydrv -a mod -p &amp;lt;PD_ID&amp;gt; -s &amp;quot;config=passthru&amp;quot;''.&lt;br /&gt;
  - Re-run ''phydrv -v'' and confirm the new state.&lt;br /&gt;
&lt;br /&gt;
== Common examples ==&lt;br /&gt;
&lt;br /&gt;
List drives:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -v&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Locate drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a locate -p 4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 to PassThru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=passthru&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Convert drive 4 back to Unconfigured:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a mod -p 4 -s &amp;quot;config=unconfig&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clear stale configuration on drive 4:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -a clear -p 4 -t staleconfig&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What the web app code confirms ==&lt;br /&gt;
&lt;br /&gt;
Relevant behavior found in the application code:&lt;br /&gt;
&lt;br /&gt;
  * Physical drive IDs come from ''pdi_FlatId''.&lt;br /&gt;
  * UI detail display uses ''PD &amp;lt;id+1&amp;gt;''.&lt;br /&gt;
  * The physical-drive settings panel offers ''Unconfigured'' and ''PassThru''.&lt;br /&gt;
  * Saving those settings issues backend ''setPhyDrvSettings''.&lt;br /&gt;
  * Advanced configuration code also toggles drives through ''setPhyDrvSettings''.&lt;br /&gt;
&lt;br /&gt;
== Limitations of this note ==&lt;br /&gt;
&lt;br /&gt;
  * This document is based on bundled help text and code inspection.&lt;br /&gt;
  * The ''cli_exeMod'' binary in this repository was not executed successfully on the current ''arm64'' host during this review.&lt;br /&gt;
  * If you run this on the original supported platform, verify syntax with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI help phydrv&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$CLI phydrv -h&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Mac OS X]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2026-03-11_at_00.45.20.png&amp;diff=9849</id>
		<title>Vaizdas:Screenshot 2026-03-11 at 00.45.20.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2026-03-11_at_00.45.20.png&amp;diff=9849"/>
		<updated>2026-03-10T22:45:50Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Cpu_killer&amp;diff=9848</id>
		<title>Cpu killer</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Cpu_killer&amp;diff=9848"/>
		<updated>2025-11-08T20:45:46Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: v2 - pervadina tik procesus kurie yra /home prefix'e taip pat atskiria ar tai binarikas ar scriptas, patikrina ar yra shebangas, t.y jeigu cmdline matosi priekyje interpretatorius&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Scriptas skirtas automatiškai killinti userių procesus kurie pastoviai ėda &amp;gt;90% cpu time. Naudoju Free Shells projektui jau eilę metų, čia jau antra scripto iteracija, pirmoji buvo parašyta ant bash.. Scriptas taip pat &amp;quot;decloakina&amp;quot; hidden procesus, t.y pakeistais pavadinimais, pervadina procesą su prefix'u &amp;quot;_too_much_cpu_time&amp;quot;. Pervadintas nepasileis automatiškai, jeigu uždėtas ant cron ar kokio kito auto paleisties mechanizmo t.y systemd-user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
CPU Killer Daemon&lt;br /&gt;
- Continuously monitors processes&lt;br /&gt;
- Kills if &amp;gt;90% CPU for 10+ minutes&lt;br /&gt;
- Renames real binary&lt;br /&gt;
- Runs as background service&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import psutil&lt;br /&gt;
import shutil&lt;br /&gt;
import time&lt;br /&gt;
import stat&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
from collections import defaultdict&lt;br /&gt;
&lt;br /&gt;
# ============================= CONFIG =============================&lt;br /&gt;
CPU_THRESHOLD = 90.0        # % CPU usage&lt;br /&gt;
TIME_THRESHOLD = 600        # seconds (10 minutes)&lt;br /&gt;
CHECK_INTERVAL = 30            # check every 30 sec&lt;br /&gt;
EXCEPTION_USERS = {'root', 'polkitd', '_chrony', 'postgres', 'nginx', 'devnull', 'zabbix', 'www-data', 'systemd-network', 'systemd-timesync', 'systemd-resolve'}  # &amp;lt;--- ADD YOUR USERS HERE&lt;br /&gt;
SAFE_RENAME_PREFIXES = ('/home/',) # Only rename files living under these prefixes&lt;br /&gt;
LOG_FILE = &amp;quot;/root/tools/cpu_killer.log&amp;quot;&lt;br /&gt;
DRY_RUN = False             # Set to True for testing (no kill/rename)&lt;br /&gt;
PID_FILE = &amp;quot;/root/tools/cpu_killer.pid&amp;quot;&lt;br /&gt;
# ==================================================================&lt;br /&gt;
&lt;br /&gt;
def _is_under_safe_prefix(p: str) -&amp;gt; bool:&lt;br /&gt;
    try:&lt;br /&gt;
        rp = Path(p).resolve().as_posix()&lt;br /&gt;
    except Exception:&lt;br /&gt;
        return False&lt;br /&gt;
    return any(rp.startswith(prefix) for prefix in SAFE_RENAME_PREFIXES)&lt;br /&gt;
&lt;br /&gt;
def _abs_from_proc_cwd(proc: psutil.Process, path: str) -&amp;gt; str:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Make path absolute using the process' cwd if it's relative.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if os.path.isabs(path):&lt;br /&gt;
        return path&lt;br /&gt;
    try:&lt;br /&gt;
        cwd = os.readlink(f&amp;quot;/proc/{proc.pid}/cwd&amp;quot;)&lt;br /&gt;
        return os.path.normpath(os.path.join(cwd, path))&lt;br /&gt;
    except Exception:&lt;br /&gt;
        return path&lt;br /&gt;
&lt;br /&gt;
def get_safe_rename_target(proc: psutil.Process) -&amp;gt; str | None:&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Return a file path that is safe to rename:&lt;br /&gt;
    - Prefer the launched script (for Python or shebang scripts)&lt;br /&gt;
    - Must be under /home/&lt;br /&gt;
    - Never return the interpreter/binary in /usr, /bin, etc.&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    try:&lt;br /&gt;
        cmd = proc.cmdline()&lt;br /&gt;
        if not cmd:&lt;br /&gt;
            return None&lt;br /&gt;
&lt;br /&gt;
        candidates = []&lt;br /&gt;
&lt;br /&gt;
        # If invoked as: python /home/user/app.py ...&lt;br /&gt;
        exe_base = os.path.basename(cmd[0])&lt;br /&gt;
        if 'python' in exe_base.lower() and len(cmd) &amp;gt;= 2:&lt;br /&gt;
            candidates.append(cmd[1])&lt;br /&gt;
&lt;br /&gt;
        # If invoked directly: /home/user/app.py (shebang)&lt;br /&gt;
        candidates.append(cmd[0])&lt;br /&gt;
&lt;br /&gt;
        # Consider only first existing file under /home/&lt;br /&gt;
        for c in candidates:&lt;br /&gt;
            c_abs = _abs_from_proc_cwd(proc, c)&lt;br /&gt;
            if not c_abs:&lt;br /&gt;
                continue&lt;br /&gt;
            try:&lt;br /&gt;
                st = os.stat(c_abs)&lt;br /&gt;
                if not stat.S_ISREG(st.st_mode):&lt;br /&gt;
                    continue&lt;br /&gt;
            except Exception:&lt;br /&gt;
                continue&lt;br /&gt;
            if _is_under_safe_prefix(c_abs):&lt;br /&gt;
                return c_abs&lt;br /&gt;
&lt;br /&gt;
        # As a last resort, fall back to real binary only if it's under /home/&lt;br /&gt;
        real_bin = get_real_binary(proc)&lt;br /&gt;
        if real_bin and _is_under_safe_prefix(real_bin):&lt;br /&gt;
            return real_bin&lt;br /&gt;
&lt;br /&gt;
        return None&lt;br /&gt;
    except Exception:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    ts = datetime.now().strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
    line = f&amp;quot;[{ts}] {msg}&amp;quot;&lt;br /&gt;
    print(line)&lt;br /&gt;
    try:&lt;br /&gt;
        with open(LOG_FILE, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
            f.write(line + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    except:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
def daemonize():&lt;br /&gt;
    if os.fork(): sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    if os.fork(): sys.exit(0)&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
    sys.stderr.flush()&lt;br /&gt;
    with open('/dev/null', 'r') as dev_null:&lt;br /&gt;
        os.dup2(dev_null.fileno(), sys.stdin.fileno())&lt;br /&gt;
    with open(LOG_FILE, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
        os.dup2(f.fileno(), sys.stdout.fileno())&lt;br /&gt;
        os.dup2(f.fileno(), sys.stderr.fileno())&lt;br /&gt;
&lt;br /&gt;
    # Write PID&lt;br /&gt;
    with open(PID_FILE, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
class ProcessTracker:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.tracked = {}  # pid -&amp;gt; {start_time, cpu_samples}&lt;br /&gt;
&lt;br /&gt;
    def update(self, proc):&lt;br /&gt;
        pid = proc.pid&lt;br /&gt;
        if pid not in self.tracked:&lt;br /&gt;
            self.tracked[pid] = {&lt;br /&gt;
                'start_time': time.time(),&lt;br /&gt;
                'cpu_samples': []&lt;br /&gt;
            }&lt;br /&gt;
        self.tracked[pid]['cpu_samples'].append(proc.cpu_percent())&lt;br /&gt;
        # Keep last 20 samples (~10 min at 30s interval)&lt;br /&gt;
        if len(self.tracked[pid]['cpu_samples']) &amp;gt; 20:&lt;br /&gt;
            self.tracked[pid]['cpu_samples'].pop(0)&lt;br /&gt;
&lt;br /&gt;
    def is_offender(self, pid):&lt;br /&gt;
        data = self.tracked.get(pid)&lt;br /&gt;
        if not data or len(data['cpu_samples']) &amp;lt; 10:&lt;br /&gt;
            return False&lt;br /&gt;
        # Average CPU over last ~5-10 min&lt;br /&gt;
        avg_cpu = sum(data['cpu_samples']) / len(data['cpu_samples'])&lt;br /&gt;
        runtime = time.time() - data['start_time']&lt;br /&gt;
        return avg_cpu &amp;gt;= CPU_THRESHOLD and runtime &amp;gt;= TIME_THRESHOLD&lt;br /&gt;
&lt;br /&gt;
    def cleanup(self, pid):&lt;br /&gt;
        self.tracked.pop(pid, None)&lt;br /&gt;
&lt;br /&gt;
tracker = ProcessTracker()&lt;br /&gt;
&lt;br /&gt;
def get_real_binary(proc):&lt;br /&gt;
    try:&lt;br /&gt;
        exe = f&amp;quot;/proc/{proc.pid}/exe&amp;quot;&lt;br /&gt;
        if not os.path.exists(exe):&lt;br /&gt;
            return None&lt;br /&gt;
        path = os.readlink(exe)&lt;br /&gt;
        if &amp;quot;(deleted)&amp;quot; in path:&lt;br /&gt;
            path = path.replace(&amp;quot; (deleted)&amp;quot;, &amp;quot;&amp;quot;).strip()&lt;br /&gt;
        return path if os.path.exists(path) else None&lt;br /&gt;
    except:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def rename_binary(bin_path):&lt;br /&gt;
    if not bin_path or not os.path.exists(bin_path):&lt;br /&gt;
        return&lt;br /&gt;
    if not _is_under_safe_prefix(bin_path):&lt;br /&gt;
        log(f&amp;quot;  -&amp;gt; Skip rename (outside safe prefixes): {bin_path}&amp;quot;)&lt;br /&gt;
        return&lt;br /&gt;
&lt;br /&gt;
    path = Path(bin_path)&lt;br /&gt;
    # keep suffix for .py, .sh, etc.&lt;br /&gt;
    suffix = path.suffix&lt;br /&gt;
    stem = path.stem&lt;br /&gt;
    new_name = path.parent / f&amp;quot;{stem}_too_much_cpu_time{suffix}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    i = 1&lt;br /&gt;
    while new_name.exists():&lt;br /&gt;
        new_name = path.parent / f&amp;quot;{stem}_too_much_cpu_time.{i}{suffix}&amp;quot;&lt;br /&gt;
        i += 1&lt;br /&gt;
&lt;br /&gt;
    log(f&amp;quot;  -&amp;gt; Renaming: {path} → {new_name}&amp;quot;)&lt;br /&gt;
    if not DRY_RUN:&lt;br /&gt;
        try:&lt;br /&gt;
            shutil.move(str(path), str(new_name))&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(f&amp;quot;  -&amp;gt; Rename failed: {e}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def kill_process(proc):&lt;br /&gt;
    try:&lt;br /&gt;
        cmd = &amp;quot; &amp;quot;.join(proc.cmdline()[:3]) + (&amp;quot;...&amp;quot; if len(proc.cmdline()) &amp;gt; 3 else &amp;quot;&amp;quot;)&lt;br /&gt;
        log(f&amp;quot;KILLING PID {proc.pid} ({cmd}) | User: {proc.username()} | CPU: ~{proc.cpu_percent():.1f}%&amp;quot;)&lt;br /&gt;
        if not DRY_RUN:&lt;br /&gt;
            proc.terminate()&lt;br /&gt;
            try:&lt;br /&gt;
                gone, alive = psutil.wait_procs([proc], timeout=5)&lt;br /&gt;
                if alive:&lt;br /&gt;
                    log(f&amp;quot;  -&amp;gt; Force kill&amp;quot;)&lt;br /&gt;
                    for p in alive:&lt;br /&gt;
                        p.kill()&lt;br /&gt;
            except:&lt;br /&gt;
                pass&lt;br /&gt;
        return True&lt;br /&gt;
    except Exception as e:&lt;br /&gt;
        log(f&amp;quot;  -&amp;gt; Kill failed: {e}&amp;quot;)&lt;br /&gt;
        return False&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    log(&amp;quot;CPU Killer started (daemon mode)&amp;quot;)&lt;br /&gt;
    seen_pids = set()&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            current_pids = {p.pid for p in psutil.process_iter()}&lt;br /&gt;
            # Cleanup dead&lt;br /&gt;
            for pid in list(tracker.tracked.keys()):&lt;br /&gt;
                if pid not in current_pids:&lt;br /&gt;
                    tracker.cleanup(pid)&lt;br /&gt;
&lt;br /&gt;
            for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'create_time', 'cmdline']):&lt;br /&gt;
                try:&lt;br /&gt;
                    username = proc.info['username']&lt;br /&gt;
                    if not username or username in EXCEPTION_USERS or username.startswith('_'):&lt;br /&gt;
                        continue&lt;br /&gt;
                    if proc.pid &amp;lt; 100:&lt;br /&gt;
                        continue&lt;br /&gt;
&lt;br /&gt;
                    # Measure CPU (short interval)&lt;br /&gt;
                    cpu = proc.cpu_percent(interval=0.1)&lt;br /&gt;
                    if cpu &amp;lt;= 0:&lt;br /&gt;
                        continue&lt;br /&gt;
&lt;br /&gt;
                    tracker.update(proc)&lt;br /&gt;
&lt;br /&gt;
                    if tracker.is_offender(proc.pid):&lt;br /&gt;
                        target = get_safe_rename_target(proc)&lt;br /&gt;
                        bin_path = get_real_binary(proc)&lt;br /&gt;
                        log_bin = bin_path if bin_path else &amp;quot;[IN-MEMORY]&amp;quot;&lt;br /&gt;
                        log(f&amp;quot;OFFENDER DETECTED: PID {proc.pid} | User: {username} | Exe: {log_bin} | Target: {target or '[none]'}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                        if kill_process(proc):&lt;br /&gt;
                            if target:&lt;br /&gt;
                                rename_binary(target)&lt;br /&gt;
                            else:&lt;br /&gt;
                                log(&amp;quot;  -&amp;gt; No safe /home/ target to rename; skipping rename.&amp;quot;)&lt;br /&gt;
                            tracker.cleanup(proc.pid)&lt;br /&gt;
&lt;br /&gt;
                except (psutil.NoSuchProcess, psutil.AccessDenied):&lt;br /&gt;
                    continue&lt;br /&gt;
&lt;br /&gt;
            time.sleep(CHECK_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
        except KeyboardInterrupt:&lt;br /&gt;
            log(&amp;quot;CPU Killer stopped by user&amp;quot;)&lt;br /&gt;
            break&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(f&amp;quot;Unexpected error: {e}&amp;quot;)&lt;br /&gt;
            time.sleep(CHECK_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
    if os.path.exists(PID_FILE):&lt;br /&gt;
        os.remove(PID_FILE)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    if len(sys.argv) &amp;gt; 1 and sys.argv[1] == &amp;quot;stop&amp;quot;:&lt;br /&gt;
        if os.path.exists(PID_FILE):&lt;br /&gt;
            with open(PID_FILE) as f:&lt;br /&gt;
                pid = int(f.read().strip())&lt;br /&gt;
            try:&lt;br /&gt;
                os.kill(pid, 15)&lt;br /&gt;
                log(f&amp;quot;Stopped CPU Killer (PID {pid})&amp;quot;)&lt;br /&gt;
            except:&lt;br /&gt;
                log(&amp;quot;Failed to stop (not running?)&amp;quot;)&lt;br /&gt;
            os.remove(PID_FILE)&lt;br /&gt;
        else:&lt;br /&gt;
            log(&amp;quot;Not running&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
    if os.path.exists(PID_FILE):&lt;br /&gt;
        log(&amp;quot;Already running!&amp;quot;)&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    daemonize()&lt;br /&gt;
    main_loop()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Systemd unit'as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=CPU Killer Daemon&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
ExecStart=/root/tools/cpu_killer.py&lt;br /&gt;
ExecStop=/root/tools/cpu_killer.py stop&lt;br /&gt;
Restart=always&lt;br /&gt;
RestartSec=10&lt;br /&gt;
StandardOutput=null&lt;br /&gt;
StandardError=journal&lt;br /&gt;
User=root&lt;br /&gt;
PIDFile=/root/tools/cpu_killer.pid&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Pagrindinis_puslapis&amp;diff=9847</id>
		<title>Pagrindinis puslapis</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Pagrindinis_puslapis&amp;diff=9847"/>
		<updated>2025-11-06T21:10:32Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Vaizdas:Logo-full-freebsd.png|150px|link=Category:FreeBSD]] [[Vaizdas:OpenBSD-logo.png|150px|link=Category:OpenBSD]] [[Vaizdas:NetBSD-tb.png|50px|link=Category:NetBSD]]&lt;br /&gt;
[[Vaizdas:Linux u2.png|100px|link=Category:Linux]] [[Vaizdas:Windows-logo.png|60px|link=Category:Windows]] [[Vaizdas:Logo-mac-transparent.gif|100px|link=Category:Mac OS X]] [[Vaizdas:Programming languages.png|150px|link=Category:Programavimas]] [[Vaizdas:MultimediaIcons rev2.png|150px|link=Category:Multimedia]]&lt;br /&gt;
[[Vaizdas:Servers.png|100px|link=Category:Tinklas]] [[Vaizdas:Black-cellphone-icon.png|100px|link=Category:Telefonai]]&lt;br /&gt;
[[Vaizdas:Apple-tablet-concept4.png|80px|link=Category:Tablets]] [[Vaizdas:Bendruomene.png|100px|link=Category:Bendruomenė]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;imagelink_backgroundas&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sveiki!'''&lt;br /&gt;
&lt;br /&gt;
Šis puslapis skirtas visiems tiems kurie ieško informacijos.&lt;br /&gt;
&lt;br /&gt;
Čia rasite patarimų bei kitos naudingos informacijos skirtos sistemų administravimui/panaudojimui, tinklų administravimui/projektavimui, programavimui bei kitiems su IT susijusiems dalykams.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tagcloud style=&amp;quot;background: transparent; padding:0; border:0;&amp;quot;&amp;gt;exclude=templates,Wikipedia_pages_with_incorrect_protection,Wikipedia_protected_templates,Protection_templates,Latest_stable_software_release_templates,Wikipedia_pages_with_incorrect_protection_templates,Citation_templates,Computing_templates,File_message_boxes,Internet_Relay_Chat_templates,People_infobox_templates,Protected_main_page_images,Protected_redirects,Puslapiai_su neteisingomis_nuorodomis_į_failus,Statybininkas,Template_sandboxes,Templates_generating_hCards,User_soft_redirects,Wikipedia_message_box_parameter_needs_fixing, Wikipedia_non-empty_soft_redirected_categories, Wikipedia_shortcut_box_first_parameter_needs_fixing, Wikipedia_soft_redirected_categories,Wikipedia_soft_redirected_project_pages,Wikipedia_soft_redirected_talk_pages,Wikipedia_soft_redirected_templates,Wikipedia_soft_redirects,Šablonas_documentation,Wikipedia_message_box_parameter_needs_fixing,Wikipedia_non-empty_soft_redirected_categories,Wikipedia_shortcut_box_first_parameter_needs_fixing,Wikipedia_soft_redirected_categories,Puslapiai_su_neteisingomis_nuorodomis_į_failus&amp;lt;/tagcloud&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Naujienos'''''&lt;br /&gt;
&lt;br /&gt;
* 2020.04.03 - Atnaujinta wiki programinė įranga.&lt;br /&gt;
&lt;br /&gt;
== Naujausi įrašai ==&lt;br /&gt;
&lt;br /&gt;
{{Special:NewPages/20}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
'''Property of [http://www.eofnet.lt EofNET] Networks. 2005-2020.'''&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Netcat&amp;diff=9846</id>
		<title>Netcat</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Netcat&amp;diff=9846"/>
		<updated>2025-11-06T21:09:53Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Netcat''' yra kompiuterinių tinklų įrankis skirtas skaityti ir į juos rašyti panaudojant [[TCP]] arba [[UDP]] tinklo jungtis. Netcat praktiškai skirtas daugiau skriptų rašymo pritaikymui, dėl jo ypač gausių galimybių. Jis pritaikomas įvairioms su kompiuteriniais tinklais ar serveriais iškilusioms problemoms pręsti. Tai ypač naudingas įrankis tiek sistemų administratoriams tiek tinklo audito ekspertams ir pradžiamoksliams kurie nagrinėja [[TCP/IP]] protokolo veikimą.&lt;br /&gt;
&lt;br /&gt;
'''Netcat''' taip pat vadinamas &amp;quot;Armijos daugiafunkciniu peiliuku skirtu TCP/IP&amp;quot;, dėl savo turimų galimybių įskaitant, prievadų skanavimą, failų siuntimą ir klausyma, taip pat jis gali būti naudojamas ir kaip &amp;quot;backdooras&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Visu interface klausymasis ==&lt;br /&gt;
 nc -l -p 8080 -s 0.0.0.0&lt;br /&gt;
Arba&lt;br /&gt;
 nc -l -p 8080 0.0.0.0 &lt;br /&gt;
== Niekada neuždaryti ==&lt;br /&gt;
 while :; do nc -l -p 8080 -k -q -1 -s 0.0.0.0; done&lt;br /&gt;
&lt;br /&gt;
== Jungtis su tam tikru ip ==&lt;br /&gt;
Jeigu mašinoje turime daug ip ir norime, kad prie nuotolinio serverio jungtumėmės nurodytu ip, pridedame parametrą -s, atrodys taip:&lt;br /&gt;
 nc -s lokalus_ip nutoles_adres.as 21&lt;br /&gt;
&lt;br /&gt;
== Backup over lan naudojant netcat ==&lt;br /&gt;
&lt;br /&gt;
Situacija, kai pradeda failinti ssd diskas ir reikia padaryti jo atsarginę kopiją į [[NAS]], tuomet užkrovus [[live cd]] ir įdėjus naują diską &amp;quot;supushinti&amp;quot; viską atgal..&lt;br /&gt;
&lt;br /&gt;
Sąvokos:&lt;br /&gt;
* '''nas.lan''' -&amp;gt; [[NAS]] kuriame bus laikoma atsarginė kopija&lt;br /&gt;
* '''pc.lan''' -&amp;gt; [[PC]] kuriame failina diskas ir keičiame jį nauju...&lt;br /&gt;
* '''pc.lan.img.gz''' -&amp;gt; Daromo backup archyvo failas&lt;br /&gt;
&lt;br /&gt;
Reikalinga, kad abiejuose pc būtų įdiegti įrankiai: '''netcat, pv, gzip'''. Duomenų suspaudimą/atspaudimą taikysime tiktai '''pc.lan''', kad bereikalingai neapkrautime '''nas.lan'''.&lt;br /&gt;
             &lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Prisijungiame prie '''nas.lan''' ir paleidžiame '''netcat''' (klausimosi režimu):&lt;br /&gt;
 nc -l -p 9000 &amp;gt; ./pc.lan.img.gz&lt;br /&gt;
Iš '''pc.lan''' pushiname disko atvaizdą į '''nas.lan''':&lt;br /&gt;
 dd if=/dev/sda bs=4M status=progress conv=noerror,sync | pv | gzip | nc nas.lan 9000&lt;br /&gt;
Abu procesai abėjose pusėse pabaigoje turėtų išsijungti automatiškai.&lt;br /&gt;
Vėliau galima patikrinti backup archyvą:&lt;br /&gt;
 gzip -t ./pc.lan.img.gz &amp;amp;&amp;amp; echo &amp;quot;Backup OK&amp;quot;&lt;br /&gt;
=== Restore ===&lt;br /&gt;
&lt;br /&gt;
Išimame iš '''pc.lan''' senajį diską ir įdedame naują, užsikrauname kokį nors [[Linux]] [[live cd]], pvz.: [[Gentoo]], [[ArchLinux]] ar kt. Susitvarkome tinklą ir paleidžiame netcat (klausimosi režimas lauks kol '''nas.lan''' pradės siųsti backup archyvą):&lt;br /&gt;
 nc -l -p 9000 | pv | gzip -dc | dd of=/dev/sda bs=4M status=progress&lt;br /&gt;
Prisijungiame prie '''nas.lan''' ir siunčiame backup archyvą:&lt;br /&gt;
 cat ./pc.lan.img.gz | nc pc.lan 9000&lt;br /&gt;
&lt;br /&gt;
[[Category:Windows]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Archlinux]]&lt;br /&gt;
[[Category:Gentoo]]&lt;br /&gt;
[[Category:CentOS]]&lt;br /&gt;
[[Category:Debian]]&lt;br /&gt;
[[Category:Ubuntu]]&lt;br /&gt;
[[Category:Slackware]]&lt;br /&gt;
[[Category:Tinklas]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Netcat&amp;diff=9845</id>
		<title>Netcat</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Netcat&amp;diff=9845"/>
		<updated>2025-11-06T20:40:36Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: dd backup naudojimas backupinti disko atvaizdą į išorinį serverį&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Netcat''' yra kompiuterinių tinklų įrankis skirtas skaityti ir į juos rašyti panaudojant [[TCP]] arba [[UDP]] tinklo jungtis. Netcat praktiškai skirtas daugiau skriptų rašymo pritaikymui, dėl jo ypač gausių galimybių. Jis pritaikomas įvairioms su kompiuteriniais tinklais ar serveriais iškilusioms problemoms pręsti. Tai ypač naudingas įrankis tiek sistemų administratoriams tiek tinklo audito ekspertams ir pradžiamoksliams kurie nagrinėja [[TCP/IP]] protokolo veikimą.&lt;br /&gt;
&lt;br /&gt;
'''Netcat''' taip pat vadinamas &amp;quot;Armijos daugiafunkciniu peiliuku skirtu TCP/IP&amp;quot;, dėl savo turimų galimybių įskaitant, prievadų skanavimą, failų siuntimą ir klausyma, taip pat jis gali būti naudojamas ir kaip &amp;quot;backdooras&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Visu interface klausymasis ==&lt;br /&gt;
 nc -l -p 8080 -s 0.0.0.0&lt;br /&gt;
Arba&lt;br /&gt;
 nc -l -p 8080 0.0.0.0 &lt;br /&gt;
== Niekada neuždaryti ==&lt;br /&gt;
 while :; do nc -l -p 8080 -k -q -1 -s 0.0.0.0; done&lt;br /&gt;
&lt;br /&gt;
== Jungtis su tam tikru ip ==&lt;br /&gt;
Jeigu mašinoje turime daug ip ir norime, kad prie nuotolinio serverio jungtumėmės nurodytu ip, pridedame parametrą -s, atrodys taip:&lt;br /&gt;
 nc -s lokalus_ip nutoles_adres.as 21&lt;br /&gt;
&lt;br /&gt;
== Backup over lan naudojant netcat ==&lt;br /&gt;
&lt;br /&gt;
Situacija, kai pradeda failinti ssd diskas ir reikia padaryti jo atsarginę kopiją į [[NAS]], tuomet užkrovus [[live cd]] ir įdėjus naują diską &amp;quot;supushinti&amp;quot; viską atgal..&lt;br /&gt;
&lt;br /&gt;
Sąvokos:&lt;br /&gt;
* '''nas.lan''' -&amp;gt; [[NAS]] kuriame bus laikoma atsarginė kopija&lt;br /&gt;
* '''pc.lan''' -&amp;gt; [[PC]] kuriame failina diskas ir keičiame jį nauju...&lt;br /&gt;
* '''pc.lan.img.gz''' -&amp;gt; Daromo backup archyvo failas&lt;br /&gt;
&lt;br /&gt;
Reikalinga, kad abiejuose pc būtų įdiegti įrankiai: '''netcat, pv, gzip'''. Duomenų suspaudimą/atspaudimą taikysime tiktai '''pc.lan''', kad bereikalingai neapkrautime '''nas.lan'''.&lt;br /&gt;
             &lt;br /&gt;
=== Backup ===&lt;br /&gt;
&lt;br /&gt;
Prisijungiame prie '''nas.lan''' ir paleidžiame '''netcat''' (klausimosi režimu):&lt;br /&gt;
 nc -l -p 9000 &amp;gt; ./pc.lan.img.gz&lt;br /&gt;
Iš '''pc.lan''' pushiname disko atvaizdą į '''nas.lan''':&lt;br /&gt;
 dd if=/dev/sda bs=4M status=progress conv=noerror,sync | pv | gzip | nc nas.lan 9000&lt;br /&gt;
Abu procesai abėjose pusėse pabaigoje turėtų išsijungti automatiškai.&lt;br /&gt;
&lt;br /&gt;
=== Restore ===&lt;br /&gt;
&lt;br /&gt;
Išimame iš '''pc.lan''' senajį diską ir įdedame naują, užsikrauname kokį nors [[Linux]] [[live cd]], pvz.: [[Gentoo]], [[ArchLinux]] ar kt. Susitvarkome tinklą ir paleidžiame netcat (klausimosi režimas lauks kol '''nas.lan''' pradės siųsti backup archyvą):&lt;br /&gt;
 nc -l -p 9000 | pv | gzip -dc | dd of=/dev/sda bs=4M status=progress&lt;br /&gt;
Prisijungiame prie '''nas.lan''' ir siunčiame backup archyvą:&lt;br /&gt;
 cat ./pc.lan.img.gz | nc pc.lan 9000&lt;br /&gt;
&lt;br /&gt;
[[Category:Windows]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Archlinux]]&lt;br /&gt;
[[Category:Gentoo]]&lt;br /&gt;
[[Category:CentOS]]&lt;br /&gt;
[[Category:Debian]]&lt;br /&gt;
[[Category:Ubuntu]]&lt;br /&gt;
[[Category:Slackware]]&lt;br /&gt;
[[Category:Tinklas]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Cpu_killer&amp;diff=9844</id>
		<title>Cpu killer</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Cpu_killer&amp;diff=9844"/>
		<updated>2025-11-02T20:45:17Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: Scriptas skirtas automatiškai killinti userių procesus kurie pastoviai ėda &amp;gt;90% cpu time. Naudoju Free Shells projektui jau eilę metų, čia jau antra scripto iteracija, pirm...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Scriptas skirtas automatiškai killinti userių procesus kurie pastoviai ėda &amp;gt;90% cpu time. Naudoju Free Shells projektui jau eilę metų, čia jau antra scripto iteracija, pirmoji buvo parašyta ant bash.. Scriptas taip pat &amp;quot;decloakina&amp;quot; hidden procesus, t.y pakeistais pavadinimais, pervadina procesą su prefix'u &amp;quot;_too_much_cpu_time&amp;quot;. Pervadintas nepasileis automatiškai, jeigu uždėtas ant cron ar kokio kito auto paleisties mechanizmo t.y systemd-user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
CPU Killer Daemon&lt;br /&gt;
- Continuously monitors processes&lt;br /&gt;
- Kills if &amp;gt;90% CPU for 10+ minutes&lt;br /&gt;
- Renames real binary&lt;br /&gt;
- Runs as background service&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import psutil&lt;br /&gt;
import shutil&lt;br /&gt;
import time&lt;br /&gt;
from datetime import datetime&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
from collections import defaultdict&lt;br /&gt;
&lt;br /&gt;
# ============================= CONFIG =============================&lt;br /&gt;
CPU_THRESHOLD = 90.0        # % CPU usage&lt;br /&gt;
TIME_THRESHOLD = 600        # seconds (10 minutes)&lt;br /&gt;
CHECK_INTERVAL = 30            # check every 30 sec&lt;br /&gt;
EXCEPTION_USERS = {'root', 'polkitd', '_chrony', 'postgres', 'nginx', 'devnull', 'zabbix', 'www-data', 'systemd-network', 'systemd-timesync', 'systemd-resolve'}  # &amp;lt;--- ADD YOUR USERS HERE&lt;br /&gt;
LOG_FILE = &amp;quot;/root/tools/cpu_killer.log&amp;quot;&lt;br /&gt;
DRY_RUN = False             # Set to True for testing (no kill/rename)&lt;br /&gt;
PID_FILE = &amp;quot;/root/tools/cpu_killer.pid&amp;quot;&lt;br /&gt;
# ==================================================================&lt;br /&gt;
&lt;br /&gt;
def log(msg):&lt;br /&gt;
    ts = datetime.now().strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
    line = f&amp;quot;[{ts}] {msg}&amp;quot;&lt;br /&gt;
    print(line)&lt;br /&gt;
    try:&lt;br /&gt;
        with open(LOG_FILE, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
            f.write(line + &amp;quot;\n&amp;quot;)&lt;br /&gt;
    except:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
def daemonize():&lt;br /&gt;
    if os.fork(): sys.exit(0)&lt;br /&gt;
    os.setsid()&lt;br /&gt;
    if os.fork(): sys.exit(0)&lt;br /&gt;
    sys.stdout.flush()&lt;br /&gt;
    sys.stderr.flush()&lt;br /&gt;
    with open('/dev/null', 'r') as dev_null:&lt;br /&gt;
        os.dup2(dev_null.fileno(), sys.stdin.fileno())&lt;br /&gt;
    with open(LOG_FILE, &amp;quot;a&amp;quot;) as f:&lt;br /&gt;
        os.dup2(f.fileno(), sys.stdout.fileno())&lt;br /&gt;
        os.dup2(f.fileno(), sys.stderr.fileno())&lt;br /&gt;
&lt;br /&gt;
    # Write PID&lt;br /&gt;
    with open(PID_FILE, &amp;quot;w&amp;quot;) as f:&lt;br /&gt;
        f.write(str(os.getpid()))&lt;br /&gt;
&lt;br /&gt;
class ProcessTracker:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.tracked = {}  # pid -&amp;gt; {start_time, cpu_samples}&lt;br /&gt;
&lt;br /&gt;
    def update(self, proc):&lt;br /&gt;
        pid = proc.pid&lt;br /&gt;
        if pid not in self.tracked:&lt;br /&gt;
            self.tracked[pid] = {&lt;br /&gt;
                'start_time': time.time(),&lt;br /&gt;
                'cpu_samples': []&lt;br /&gt;
            }&lt;br /&gt;
        self.tracked[pid]['cpu_samples'].append(proc.cpu_percent())&lt;br /&gt;
        # Keep last 20 samples (~10 min at 30s interval)&lt;br /&gt;
        if len(self.tracked[pid]['cpu_samples']) &amp;gt; 20:&lt;br /&gt;
            self.tracked[pid]['cpu_samples'].pop(0)&lt;br /&gt;
&lt;br /&gt;
    def is_offender(self, pid):&lt;br /&gt;
        data = self.tracked.get(pid)&lt;br /&gt;
        if not data or len(data['cpu_samples']) &amp;lt; 10:&lt;br /&gt;
            return False&lt;br /&gt;
        # Average CPU over last ~5-10 min&lt;br /&gt;
        avg_cpu = sum(data['cpu_samples']) / len(data['cpu_samples'])&lt;br /&gt;
        runtime = time.time() - data['start_time']&lt;br /&gt;
        return avg_cpu &amp;gt;= CPU_THRESHOLD and runtime &amp;gt;= TIME_THRESHOLD&lt;br /&gt;
&lt;br /&gt;
    def cleanup(self, pid):&lt;br /&gt;
        self.tracked.pop(pid, None)&lt;br /&gt;
&lt;br /&gt;
tracker = ProcessTracker()&lt;br /&gt;
&lt;br /&gt;
def get_real_binary(proc):&lt;br /&gt;
    try:&lt;br /&gt;
        exe = f&amp;quot;/proc/{proc.pid}/exe&amp;quot;&lt;br /&gt;
        if not os.path.exists(exe):&lt;br /&gt;
            return None&lt;br /&gt;
        path = os.readlink(exe)&lt;br /&gt;
        if &amp;quot;(deleted)&amp;quot; in path:&lt;br /&gt;
            path = path.replace(&amp;quot; (deleted)&amp;quot;, &amp;quot;&amp;quot;).strip()&lt;br /&gt;
        return path if os.path.exists(path) else None&lt;br /&gt;
    except:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
def rename_binary(bin_path):&lt;br /&gt;
    if not bin_path or not os.path.exists(bin_path):&lt;br /&gt;
        return&lt;br /&gt;
    path = Path(bin_path)&lt;br /&gt;
    new_name = path.parent / f&amp;quot;{path.stem}_too_much_cpu_time{path.suffix}&amp;quot;&lt;br /&gt;
    i = 1&lt;br /&gt;
    while new_name.exists():&lt;br /&gt;
        new_name = path.parent / f&amp;quot;{path.stem}_too_much_cpu_time.{i}{path.suffix}&amp;quot;&lt;br /&gt;
        i += 1&lt;br /&gt;
    log(f&amp;quot;  -&amp;gt; Renaming: {path.name} → {new_name.name}&amp;quot;)&lt;br /&gt;
    if not DRY_RUN:&lt;br /&gt;
        try:&lt;br /&gt;
            shutil.move(str(path), str(new_name))&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(f&amp;quot;  -&amp;gt; Rename failed: {e}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def kill_process(proc):&lt;br /&gt;
    try:&lt;br /&gt;
        cmd = &amp;quot; &amp;quot;.join(proc.cmdline()[:3]) + (&amp;quot;...&amp;quot; if len(proc.cmdline()) &amp;gt; 3 else &amp;quot;&amp;quot;)&lt;br /&gt;
        log(f&amp;quot;KILLING PID {proc.pid} ({cmd}) | User: {proc.username()} | CPU: ~{proc.cpu_percent():.1f}%&amp;quot;)&lt;br /&gt;
        if not DRY_RUN:&lt;br /&gt;
            proc.terminate()&lt;br /&gt;
            try:&lt;br /&gt;
                gone, alive = psutil.wait_procs([proc], timeout=5)&lt;br /&gt;
                if alive:&lt;br /&gt;
                    log(f&amp;quot;  -&amp;gt; Force kill&amp;quot;)&lt;br /&gt;
                    for p in alive:&lt;br /&gt;
                        p.kill()&lt;br /&gt;
            except:&lt;br /&gt;
                pass&lt;br /&gt;
        return True&lt;br /&gt;
    except Exception as e:&lt;br /&gt;
        log(f&amp;quot;  -&amp;gt; Kill failed: {e}&amp;quot;)&lt;br /&gt;
        return False&lt;br /&gt;
&lt;br /&gt;
def main_loop():&lt;br /&gt;
    log(&amp;quot;CPU Killer started (daemon mode)&amp;quot;)&lt;br /&gt;
    seen_pids = set()&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            current_pids = {p.pid for p in psutil.process_iter()}&lt;br /&gt;
            # Cleanup dead&lt;br /&gt;
            for pid in list(tracker.tracked.keys()):&lt;br /&gt;
                if pid not in current_pids:&lt;br /&gt;
                    tracker.cleanup(pid)&lt;br /&gt;
&lt;br /&gt;
            for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'create_time', 'cmdline']):&lt;br /&gt;
                try:&lt;br /&gt;
                    username = proc.info['username']&lt;br /&gt;
                    if not username or username in EXCEPTION_USERS or username.startswith('_'):&lt;br /&gt;
                        continue&lt;br /&gt;
                    if proc.pid &amp;lt; 100:&lt;br /&gt;
                        continue&lt;br /&gt;
&lt;br /&gt;
                    # Measure CPU (short interval)&lt;br /&gt;
                    cpu = proc.cpu_percent(interval=0.1)&lt;br /&gt;
                    if cpu &amp;lt;= 0:&lt;br /&gt;
                        continue&lt;br /&gt;
&lt;br /&gt;
                    tracker.update(proc)&lt;br /&gt;
&lt;br /&gt;
                    if tracker.is_offender(proc.pid):&lt;br /&gt;
                        bin_path = get_real_binary(proc)&lt;br /&gt;
                        if bin_path:&lt;br /&gt;
                            log(f&amp;quot;OFFENDER DETECTED: PID {proc.pid} | User: {username} | Binary: {bin_path}&amp;quot;)&lt;br /&gt;
                        else:&lt;br /&gt;
                            log(f&amp;quot;OFFENDER DETECTED: PID {proc.pid} | User: {username} | Binary: [IN-MEMORY]&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                        if kill_process(proc):&lt;br /&gt;
                            if bin_path:&lt;br /&gt;
                                rename_binary(bin_path)&lt;br /&gt;
                            tracker.cleanup(proc.pid)&lt;br /&gt;
&lt;br /&gt;
                except (psutil.NoSuchProcess, psutil.AccessDenied):&lt;br /&gt;
                    continue&lt;br /&gt;
&lt;br /&gt;
            time.sleep(CHECK_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
        except KeyboardInterrupt:&lt;br /&gt;
            log(&amp;quot;CPU Killer stopped by user&amp;quot;)&lt;br /&gt;
            break&lt;br /&gt;
        except Exception as e:&lt;br /&gt;
            log(f&amp;quot;Unexpected error: {e}&amp;quot;)&lt;br /&gt;
            time.sleep(CHECK_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
    if os.path.exists(PID_FILE):&lt;br /&gt;
        os.remove(PID_FILE)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    if len(sys.argv) &amp;gt; 1 and sys.argv[1] == &amp;quot;stop&amp;quot;:&lt;br /&gt;
        if os.path.exists(PID_FILE):&lt;br /&gt;
            with open(PID_FILE) as f:&lt;br /&gt;
                pid = int(f.read().strip())&lt;br /&gt;
            try:&lt;br /&gt;
                os.kill(pid, 15)&lt;br /&gt;
                log(f&amp;quot;Stopped CPU Killer (PID {pid})&amp;quot;)&lt;br /&gt;
            except:&lt;br /&gt;
                log(&amp;quot;Failed to stop (not running?)&amp;quot;)&lt;br /&gt;
            os.remove(PID_FILE)&lt;br /&gt;
        else:&lt;br /&gt;
            log(&amp;quot;Not running&amp;quot;)&lt;br /&gt;
        sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
    if os.path.exists(PID_FILE):&lt;br /&gt;
        log(&amp;quot;Already running!&amp;quot;)&lt;br /&gt;
        sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
    daemonize()&lt;br /&gt;
    main_loop()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Systemd unit'as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=CPU Killer Daemon&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
ExecStart=/root/tools/cpu_killer.py&lt;br /&gt;
ExecStop=/root/tools/cpu_killer.py stop&lt;br /&gt;
Restart=always&lt;br /&gt;
RestartSec=10&lt;br /&gt;
StandardOutput=null&lt;br /&gt;
StandardError=journal&lt;br /&gt;
User=root&lt;br /&gt;
PIDFile=/root/tools/cpu_killer.pid&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9843</id>
		<title>UConsole</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9843"/>
		<updated>2025-10-28T21:25:37Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vidinis USB ==&lt;br /&gt;
&lt;br /&gt;
Hackas kuris leidžia pasidaryti vidinį usb portą, skirtą pvz.: papildomam vidiniam [[wifi]], [[sdr]] ar [[LoRa]] įrenginiui.&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 20251025 124247-2.png|1200px|frameless]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Usb-3-pinout.webp|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack1.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack2.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack3.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=RTL8812AU&amp;diff=9842</id>
		<title>RTL8812AU</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=RTL8812AU&amp;diff=9842"/>
		<updated>2025-10-28T21:25:09Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Linux Drivers ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/morrownr/8812au-20210820 Linux Driver for USB WiFi Adapters that are based on the RTL8812AU Chipset]&lt;br /&gt;
&lt;br /&gt;
== RTL8812AU/21AU and RTL8814AU driver with monitor mode and frame injection ==&lt;br /&gt;
&lt;br /&gt;
Sistemoje jau turėtų būti esamo kernelio headeriai.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install dkms build-essential&lt;br /&gt;
 git clone https://github.com/aircrack-ng/rtl8812au.git&lt;br /&gt;
 cd rtl8812au&lt;br /&gt;
 sudo make dkms_install&lt;br /&gt;
&lt;br /&gt;
[[Category:Tinklas]]&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
{{Template:Distributions}}&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=RTL8812AU&amp;diff=9841</id>
		<title>RTL8812AU</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=RTL8812AU&amp;diff=9841"/>
		<updated>2025-10-28T21:24:55Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Linux Drivers ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/morrownr/8812au-20210820 Linux Driver for USB WiFi Adapters that are based on the RTL8812AU Chipset]&lt;br /&gt;
&lt;br /&gt;
== RTL8812AU/21AU and RTL8814AU driver with monitor mode and frame injection ==&lt;br /&gt;
&lt;br /&gt;
Sistemoje jau turėtų būti esamo kernelio headeriai.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install dkms build-essential&lt;br /&gt;
 git clone https://github.com/aircrack-ng/rtl8812au.git&lt;br /&gt;
 cd rtl8812au&lt;br /&gt;
 sudo make dkms_install&lt;br /&gt;
&lt;br /&gt;
[[Category:Tinkas]]&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
{{Template:Distributions}}&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9840</id>
		<title>UConsole</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9840"/>
		<updated>2025-10-25T13:37:34Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vidinis USB ==&lt;br /&gt;
&lt;br /&gt;
Hackas kuris leidžia pasidaryti vidinį usb portą, skirtą pvz.: papildomam vidiniam [[wifi[[, [[sdr]] ar [[LoRa]] įrenginiui.&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 20251025 124247-2.png|1200px|frameless]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Usb-3-pinout.webp|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack1.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack2.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Uconsole internal usb hack3.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack3.jpg&amp;diff=9839</id>
		<title>Vaizdas:Uconsole internal usb hack3.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack3.jpg&amp;diff=9839"/>
		<updated>2025-10-25T13:34:20Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack2.jpg&amp;diff=9838</id>
		<title>Vaizdas:Uconsole internal usb hack2.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack2.jpg&amp;diff=9838"/>
		<updated>2025-10-25T13:33:53Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack1.jpg&amp;diff=9837</id>
		<title>Vaizdas:Uconsole internal usb hack1.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Uconsole_internal_usb_hack1.jpg&amp;diff=9837"/>
		<updated>2025-10-25T13:33:27Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9836</id>
		<title>UConsole</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9836"/>
		<updated>2025-10-25T11:57:31Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vidinis USB ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 20251025 124247-2.png|1200px|frameless]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Usb-3-pinout.webp|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Usb-3-pinout.webp&amp;diff=9835</id>
		<title>Vaizdas:Usb-3-pinout.webp</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Usb-3-pinout.webp&amp;diff=9835"/>
		<updated>2025-10-25T11:57:13Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9834</id>
		<title>UConsole</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=UConsole&amp;diff=9834"/>
		<updated>2025-10-25T11:05:12Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: == Vidinis USB ==  frameless  Category:Hardware&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vidinis USB ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 20251025 124247-2.png|1200px|frameless]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_20251025_124247-2.png&amp;diff=9833</id>
		<title>Vaizdas:Screenshot 20251025 124247-2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_20251025_124247-2.png&amp;diff=9833"/>
		<updated>2025-10-25T11:03:48Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Aiva&amp;diff=9832</id>
		<title>Aiva</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Aiva&amp;diff=9832"/>
		<updated>2025-10-18T17:35:54Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Kaip paleisti ant Linux naudojant Wine aprašyta [[Aiva wine|čia]].&lt;br /&gt;
&lt;br /&gt;
== Naujas deploymentas ==&lt;br /&gt;
&lt;br /&gt;
Paredaguojam db parametrus '''api/db.php''' ir '''vb1/config.php''' failuose, taip pat mysql'e reikia pakeisti įrašus odbc connectoriaus ir ftp loginų:&lt;br /&gt;
 update catalogue_login set url='aiva.domenas.lt', odbc_par = 'duombazes_name;duombazes_user;duombazes_pass;aiva.domenas.lt', xftpserv = 'aiva.domenas.lt', xftpserv_par = 'ftpuser;ftppass', ximgadr = '&amp;lt;nowiki&amp;gt;http://aiva.domenas.lt/images/goods&amp;lt;/nowiki&amp;gt;' where id = 1;&lt;br /&gt;
&lt;br /&gt;
Kliente keičiamas '''config.ini''' ir ten įrašomas api endpointo hostas:&lt;br /&gt;
 [MAIN]&lt;br /&gt;
 IP=aiva.domenas.lt&lt;br /&gt;
&lt;br /&gt;
== Klaida neautorizuota darbo vieta ==&lt;br /&gt;
&lt;br /&gt;
Pažiūrim įjunge MySQL log:&lt;br /&gt;
 SET GLOBAL general_log = ON;&lt;br /&gt;
 tail -f /var/log/mysql/mysql.log |grep select|grep -vE &amp;quot;scg|tiekejai|pg_seima|goods_v|scdkiek&amp;quot;&lt;br /&gt;
Rodys kažką panašaus į &lt;br /&gt;
 select v_id,akt_date,akt_ip,akt_host,akt_nr from admin_dvietos where protect='51096786716' and del_date is NULL&lt;br /&gt;
Reikia atnaujinti esamą įrašą arba įrašyti naują su '''protect''' kintamuoju kurio ieško:&lt;br /&gt;
 update admin_dvietos set akt_ip = '192.168.20', akt_host = 'legion7', protect='51096786716' where v_id = 56;&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Aiva&amp;diff=9831</id>
		<title>Aiva</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Aiva&amp;diff=9831"/>
		<updated>2025-10-18T17:26:55Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis:  Kaip paleisti ant Linux naudojant Wine aprašyta čia.   == Klaida neautorizuota darbo vieta ==  Pažiūrim įjunge MySQL log:  SET GLOBAL general_log = ON;  tail...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Kaip paleisti ant Linux naudojant Wine aprašyta [[Aiva wine|čia]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Klaida neautorizuota darbo vieta ==&lt;br /&gt;
&lt;br /&gt;
Pažiūrim įjunge MySQL log:&lt;br /&gt;
 SET GLOBAL general_log = ON;&lt;br /&gt;
 tail -f /var/log/mysql/mysql.log |grep select|grep -vE &amp;quot;scg|tiekejai|pg_seima|goods_v|scdkiek&amp;quot;&lt;br /&gt;
Rodys kažką panašaus į &lt;br /&gt;
 select v_id,akt_date,akt_ip,akt_host,akt_nr from admin_dvietos where protect='51096786716' and del_date is NULL&lt;br /&gt;
Reikia atnaujinti esamą įrašą arba įrašyti naują su '''protect''' kintamuoju kurio ieško:&lt;br /&gt;
 update admin_dvietos set akt_ip = '192.168.20', akt_host = 'legion7', protect='51096786716' where v_id = 56;&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Jumpserver&amp;diff=9830</id>
		<title>Jumpserver</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Jumpserver&amp;diff=9830"/>
		<updated>2025-10-17T12:57:17Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis:   mkdir -p /srv/dockers/jumpserver/dbdata  mkdir -p /srv/dockers/jumpserver/jsdata  Susigeneruojame '''SECRET_KEY''' ir '''BOOTSTRAP_TOKEN''':  openssl rand -base64 48  &amp;lt;syntaxhi...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
 mkdir -p /srv/dockers/jumpserver/dbdata&lt;br /&gt;
 mkdir -p /srv/dockers/jumpserver/jsdata&lt;br /&gt;
&lt;br /&gt;
Susigeneruojame '''SECRET_KEY''' ir '''BOOTSTRAP_TOKEN''':&lt;br /&gt;
 openssl rand -base64 48&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
# https://github.com/jumpserver/Dockerfile/tree/master/allinone&lt;br /&gt;
services:&lt;br /&gt;
  jumpserver:&lt;br /&gt;
    container_name: jumpserver&lt;br /&gt;
    image: jumpserver/jms_all&lt;br /&gt;
    volumes:&lt;br /&gt;
      - jsdata:/opt/data&lt;br /&gt;
      - pgdata:/var/lib/postgresql&lt;br /&gt;
    networks:&lt;br /&gt;
     - traefik&lt;br /&gt;
    ports:&lt;br /&gt;
     - 2222:2222&lt;br /&gt;
    environment:&lt;br /&gt;
      TZ: &amp;quot;Europe/Vilnius&amp;quot;&lt;br /&gt;
      SECRET_KEY: &amp;quot;xxx&amp;quot;&lt;br /&gt;
      BOOTSTRAP_TOKEN: &amp;quot;xxx&amp;quot;&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    labels:&lt;br /&gt;
      - traefik.enable=true&lt;br /&gt;
      - traefik.docker.network=traefik&lt;br /&gt;
      - &amp;quot;traefik.http.routers.jumpserver.rule=Host(`jumpserver.domenas.lt`)&amp;quot;&lt;br /&gt;
      - &amp;quot;traefik.http.services.jumpserver.loadbalancer.server.port=80&amp;quot;&lt;br /&gt;
    # resources limit&lt;br /&gt;
    mem_limit: 2G&lt;br /&gt;
    cpus: 3.0&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  traefik:&lt;br /&gt;
    external: true&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  pgdata:&lt;br /&gt;
    driver: local&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: none&lt;br /&gt;
      o: bind&lt;br /&gt;
      device: /srv/dockers/jumpserver/dbdata&lt;br /&gt;
  jsdata:&lt;br /&gt;
    driver: local&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      type: none&lt;br /&gt;
      o: bind&lt;br /&gt;
      device: /srv/dockers/jumpserver/jsdata&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Docker]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9829</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9829"/>
		<updated>2025-10-07T19:39:03Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: /* Rezultatas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dėžutė iš Senukų arba Ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijungiame mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijungiame prie žemės (GND).&lt;br /&gt;
* Prilituojame keramikinį kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išvedame trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikiname, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
=== water_level.yaml ===&lt;br /&gt;
&lt;br /&gt;
Pagrindinis esphome aprašas/kodas:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
substitutions:&lt;br /&gt;
  device_name: waterlevel-qdy30b&lt;br /&gt;
  friendly_name: &amp;quot;Water Level&amp;quot;&lt;br /&gt;
  r_shunt_ohm: &amp;quot;47.0&amp;quot;         # 47 Ω&lt;br /&gt;
  max_depth_m: &amp;quot;5.0&amp;quot;          # probe range max (meters)&lt;br /&gt;
  zero_offset_cm: &amp;quot;-6.0&amp;quot;      # offset calibration: 33 → 27 cm, so -6 cm&lt;br /&gt;
  threshold_max_cm: &amp;quot;500.0&amp;quot;   # 5.0 m × 100 = 500 cm&lt;br /&gt;
  relay_gpio: GPIO15          # Board relay pin which is soldered to&lt;br /&gt;
&lt;br /&gt;
esphome:&lt;br /&gt;
  name: ${device_name}&lt;br /&gt;
  on_boot:&lt;br /&gt;
    priority: 800&lt;br /&gt;
    then:&lt;br /&gt;
      - delay: 500ms&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
preferences:&lt;br /&gt;
  flash_write_interval: 10s&lt;br /&gt;
&lt;br /&gt;
esp8266:&lt;br /&gt;
  board: esp12e&lt;br /&gt;
  restore_from_flash: true     # restore states after power off&lt;br /&gt;
&lt;br /&gt;
wifi:&lt;br /&gt;
  ssid: !secret wifi_ap&lt;br /&gt;
  password: !secret wifi_password&lt;br /&gt;
  ap:                      # fallback AP if Wi-Fi fails&lt;br /&gt;
    ssid: &amp;quot;${device_name}_AP&amp;quot;&lt;br /&gt;
    password: !secret wifi_direct&lt;br /&gt;
&lt;br /&gt;
mqtt:&lt;br /&gt;
  broker: !secret mqtt_broker&lt;br /&gt;
  client_id: ${device_name}-client&lt;br /&gt;
  username: water_level&lt;br /&gt;
  password: MyMQTTPassword&lt;br /&gt;
  discovery: true&lt;br /&gt;
&lt;br /&gt;
logger:&lt;br /&gt;
ota:&lt;br /&gt;
  - platform: esphome&lt;br /&gt;
web_server:               # small built-in web page for quick checks&lt;br /&gt;
  port: 80&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --- RELAY (physical output) ---&lt;br /&gt;
switch:&lt;br /&gt;
  - platform: gpio&lt;br /&gt;
    id: pump_relay&lt;br /&gt;
    name: &amp;quot;${friendly_name} Relay&amp;quot;&lt;br /&gt;
    pin:&lt;br /&gt;
      number: ${relay_gpio}&lt;br /&gt;
      inverted: false        # set to true if your relay is active-LOW&lt;br /&gt;
    restore_mode: RESTORE_DEFAULT_OFF   # restores last known state (if none saved, default OFF)&lt;br /&gt;
&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: auto_enable&lt;br /&gt;
    name: &amp;quot;${friendly_name} Pump Automation&amp;quot;&lt;br /&gt;
    optimistic: true&lt;br /&gt;
    restore_mode: RESTORE_DEFAULT_OFF  # restores last saved; defaults OFF if none yet&lt;br /&gt;
    turn_on_action:&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
    turn_off_action:&lt;br /&gt;
      - logger.log: &amp;quot;Automation disabled — relay left unchanged.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --- SENSORS ---&lt;br /&gt;
sensor:&lt;br /&gt;
  # Raw voltage across the shunt (A0 is 0..1.0 V on ESP12F)&lt;br /&gt;
  - platform: adc&lt;br /&gt;
    pin: A0&lt;br /&gt;
    id: loop_voltage&lt;br /&gt;
    name: &amp;quot;${friendly_name} Loop Voltage&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;V&amp;quot;&lt;br /&gt;
    accuracy_decimals: 3&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    filters:&lt;br /&gt;
      # light smoothing; A0 can be a bit noisy&lt;br /&gt;
      - median:&lt;br /&gt;
          window_size: 7&lt;br /&gt;
          send_every: 3&lt;br /&gt;
          send_first_at: 1&lt;br /&gt;
&lt;br /&gt;
  # Convert V -&amp;gt; current (mA): I = V / R * 1000&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: loop_current&lt;br /&gt;
    name: &amp;quot;${friendly_name} Loop Current&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;mA&amp;quot;&lt;br /&gt;
    accuracy_decimals: 2&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      return (id(loop_voltage).state / ${r_shunt_ohm}) * 1000.0;&lt;br /&gt;
    filters:&lt;br /&gt;
      # keep values in a sane range&lt;br /&gt;
      - clamp:&lt;br /&gt;
          min_value: 0.0&lt;br /&gt;
          max_value: 30.0&lt;br /&gt;
&lt;br /&gt;
  - platform: wifi_signal&lt;br /&gt;
    name: &amp;quot;${friendly_name} WiFi RSSI&amp;quot;&lt;br /&gt;
    update_interval: 30s&lt;br /&gt;
  - platform: uptime&lt;br /&gt;
    name: &amp;quot;${friendly_name} Uptime&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Depth in centimeters (from the computed meters)&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: water_depth_cm&lt;br /&gt;
    name: &amp;quot;${friendly_name} Depth CM&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;cm&amp;quot;&lt;br /&gt;
    device_class: distance&lt;br /&gt;
    state_class: measurement&lt;br /&gt;
    accuracy_decimals: 0            # whole centimeters; set 1 if you want 0.1 cm&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      // reuse the meters reading we already compute&lt;br /&gt;
      return id(water_depth).state * 100.0;&lt;br /&gt;
    on_value:&lt;br /&gt;
      then:&lt;br /&gt;
        - lambda: |-&lt;br /&gt;
            id(apply_control).execute();&lt;br /&gt;
&lt;br /&gt;
  # Map 4–20 mA to 0–MAX_DEPTH meters&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: water_depth&lt;br /&gt;
    name: &amp;quot;${friendly_name} Depth&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;m&amp;quot;&lt;br /&gt;
    accuracy_decimals: 2&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      const float I = id(loop_current).state; // mA&lt;br /&gt;
      float d = (I - 4.0f) / 16.0f * ${max_depth_m}; // ideal meters&lt;br /&gt;
      d += (${zero_offset_cm} / 100.0f);             // apply offset in meters&lt;br /&gt;
      if (d &amp;lt; 0.0f) d = 0.0f;&lt;br /&gt;
      if (d &amp;gt; ${max_depth_m}) d = ${max_depth_m};&lt;br /&gt;
      return d;&lt;br /&gt;
    filters:&lt;br /&gt;
      - throttle: 1s&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
number:&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: threshold_cm&lt;br /&gt;
    name: &amp;quot;${friendly_name} Threshold (cm)&amp;quot;&lt;br /&gt;
    min_value: 0.0&lt;br /&gt;
    max_value: ${threshold_max_cm}   # must be a number, not a lambda&lt;br /&gt;
    step: 1.0&lt;br /&gt;
    optimistic: true&lt;br /&gt;
    restore_value: true&lt;br /&gt;
    initial_value: 30.0&lt;br /&gt;
    set_action:&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
&lt;br /&gt;
# Optional: handy extras&lt;br /&gt;
text_sensor:&lt;br /&gt;
  - platform: wifi_info&lt;br /&gt;
    ip_address:&lt;br /&gt;
      name: &amp;quot;${friendly_name} IP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
  - id: apply_control&lt;br /&gt;
    mode: restart&lt;br /&gt;
    then:&lt;br /&gt;
      - if:&lt;br /&gt;
          condition:&lt;br /&gt;
            switch.is_on: auto_enable&lt;br /&gt;
          then:&lt;br /&gt;
            - if:&lt;br /&gt;
                condition:&lt;br /&gt;
                  lambda: |-&lt;br /&gt;
                    return id(water_depth_cm).state &amp;gt; id(threshold_cm).state;&lt;br /&gt;
                then:&lt;br /&gt;
                  - if:&lt;br /&gt;
                      condition:&lt;br /&gt;
                        switch.is_off: pump_relay&lt;br /&gt;
                      then:&lt;br /&gt;
                        - logger.log: &amp;quot;Automation: depth &amp;gt; threshold → Relay ON&amp;quot;&lt;br /&gt;
                        - switch.turn_on: pump_relay&lt;br /&gt;
                else:&lt;br /&gt;
                  - if:&lt;br /&gt;
                      condition:&lt;br /&gt;
                        switch.is_on: pump_relay&lt;br /&gt;
                      then:&lt;br /&gt;
                        - logger.log: &amp;quot;Automation: depth ≤ threshold → Relay OFF&amp;quot;&lt;br /&gt;
                        - switch.turn_off: pump_relay&lt;br /&gt;
          else:&lt;br /&gt;
            - logger.log: &amp;quot;Automation disabled — no action taken.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== secrets.yaml ===&lt;br /&gt;
&lt;br /&gt;
Šiame faile aprašoma wifi/mqtt/slaptažodžiai.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
wifi_ap: SSID&lt;br /&gt;
wifi_password: 123456789&lt;br /&gt;
wifi_direct: 123456789&lt;br /&gt;
mqtt_broker: 192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Norint, kad veiktų rėlė taip pat reikia sulituoti kartu pinus: '''Relay + 1015'''.&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level monitoring box1.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level monitoring box2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.50.23.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Kaip matome galime nustatyti kiek CM yra kritinis taškas, žemiau jo relė išsijungia, taip pat galima šią automatiką išjungti arba įjungti. Įjungimo išjungimo būsenos tai pat saugomos po power loss ar atsitiktinių elektros atjungimų, kas yra būtina išlaikant testinumą. Taipogi galima rankiniu būdu valdyti rėlę prieš tai išjungus automatiką. Pagal nutylėjimą pirmam leidimui visos pozicijos yra išjungtos.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_monitoring_box2.jpg&amp;diff=9828</id>
		<title>Vaizdas:Water level monitoring box2.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_monitoring_box2.jpg&amp;diff=9828"/>
		<updated>2025-10-07T19:38:46Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_monitoring_box1.jpg&amp;diff=9827</id>
		<title>Vaizdas:Water level monitoring box1.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_monitoring_box1.jpg&amp;diff=9827"/>
		<updated>2025-10-07T19:38:26Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9826</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9826"/>
		<updated>2025-10-06T20:15:46Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dėžutė iš Senukų arba Ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijungiame mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijungiame prie žemės (GND).&lt;br /&gt;
* Prilituojame keramikinį kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išvedame trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikiname, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
=== water_level.yaml ===&lt;br /&gt;
&lt;br /&gt;
Pagrindinis esphome aprašas/kodas:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
substitutions:&lt;br /&gt;
  device_name: waterlevel-qdy30b&lt;br /&gt;
  friendly_name: &amp;quot;Water Level&amp;quot;&lt;br /&gt;
  r_shunt_ohm: &amp;quot;47.0&amp;quot;         # 47 Ω&lt;br /&gt;
  max_depth_m: &amp;quot;5.0&amp;quot;          # probe range max (meters)&lt;br /&gt;
  zero_offset_cm: &amp;quot;-6.0&amp;quot;      # offset calibration: 33 → 27 cm, so -6 cm&lt;br /&gt;
  threshold_max_cm: &amp;quot;500.0&amp;quot;   # 5.0 m × 100 = 500 cm&lt;br /&gt;
  relay_gpio: GPIO15          # Board relay pin which is soldered to&lt;br /&gt;
&lt;br /&gt;
esphome:&lt;br /&gt;
  name: ${device_name}&lt;br /&gt;
  on_boot:&lt;br /&gt;
    priority: 800&lt;br /&gt;
    then:&lt;br /&gt;
      - delay: 500ms&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
preferences:&lt;br /&gt;
  flash_write_interval: 10s&lt;br /&gt;
&lt;br /&gt;
esp8266:&lt;br /&gt;
  board: esp12e&lt;br /&gt;
  restore_from_flash: true     # restore states after power off&lt;br /&gt;
&lt;br /&gt;
wifi:&lt;br /&gt;
  ssid: !secret wifi_ap&lt;br /&gt;
  password: !secret wifi_password&lt;br /&gt;
  ap:                      # fallback AP if Wi-Fi fails&lt;br /&gt;
    ssid: &amp;quot;${device_name}_AP&amp;quot;&lt;br /&gt;
    password: !secret wifi_direct&lt;br /&gt;
&lt;br /&gt;
mqtt:&lt;br /&gt;
  broker: !secret mqtt_broker&lt;br /&gt;
  client_id: ${device_name}-client&lt;br /&gt;
  username: water_level&lt;br /&gt;
  password: MyMQTTPassword&lt;br /&gt;
  discovery: true&lt;br /&gt;
&lt;br /&gt;
logger:&lt;br /&gt;
ota:&lt;br /&gt;
  - platform: esphome&lt;br /&gt;
web_server:               # small built-in web page for quick checks&lt;br /&gt;
  port: 80&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --- RELAY (physical output) ---&lt;br /&gt;
switch:&lt;br /&gt;
  - platform: gpio&lt;br /&gt;
    id: pump_relay&lt;br /&gt;
    name: &amp;quot;${friendly_name} Relay&amp;quot;&lt;br /&gt;
    pin:&lt;br /&gt;
      number: ${relay_gpio}&lt;br /&gt;
      inverted: false        # set to true if your relay is active-LOW&lt;br /&gt;
    restore_mode: RESTORE_DEFAULT_OFF   # restores last known state (if none saved, default OFF)&lt;br /&gt;
&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: auto_enable&lt;br /&gt;
    name: &amp;quot;${friendly_name} Pump Automation&amp;quot;&lt;br /&gt;
    optimistic: true&lt;br /&gt;
    restore_mode: RESTORE_DEFAULT_OFF  # restores last saved; defaults OFF if none yet&lt;br /&gt;
    turn_on_action:&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
    turn_off_action:&lt;br /&gt;
      - logger.log: &amp;quot;Automation disabled — relay left unchanged.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# --- SENSORS ---&lt;br /&gt;
sensor:&lt;br /&gt;
  # Raw voltage across the shunt (A0 is 0..1.0 V on ESP12F)&lt;br /&gt;
  - platform: adc&lt;br /&gt;
    pin: A0&lt;br /&gt;
    id: loop_voltage&lt;br /&gt;
    name: &amp;quot;${friendly_name} Loop Voltage&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;V&amp;quot;&lt;br /&gt;
    accuracy_decimals: 3&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    filters:&lt;br /&gt;
      # light smoothing; A0 can be a bit noisy&lt;br /&gt;
      - median:&lt;br /&gt;
          window_size: 7&lt;br /&gt;
          send_every: 3&lt;br /&gt;
          send_first_at: 1&lt;br /&gt;
&lt;br /&gt;
  # Convert V -&amp;gt; current (mA): I = V / R * 1000&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: loop_current&lt;br /&gt;
    name: &amp;quot;${friendly_name} Loop Current&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;mA&amp;quot;&lt;br /&gt;
    accuracy_decimals: 2&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      return (id(loop_voltage).state / ${r_shunt_ohm}) * 1000.0;&lt;br /&gt;
    filters:&lt;br /&gt;
      # keep values in a sane range&lt;br /&gt;
      - clamp:&lt;br /&gt;
          min_value: 0.0&lt;br /&gt;
          max_value: 30.0&lt;br /&gt;
&lt;br /&gt;
  - platform: wifi_signal&lt;br /&gt;
    name: &amp;quot;${friendly_name} WiFi RSSI&amp;quot;&lt;br /&gt;
    update_interval: 30s&lt;br /&gt;
  - platform: uptime&lt;br /&gt;
    name: &amp;quot;${friendly_name} Uptime&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Depth in centimeters (from the computed meters)&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: water_depth_cm&lt;br /&gt;
    name: &amp;quot;${friendly_name} Depth CM&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;cm&amp;quot;&lt;br /&gt;
    device_class: distance&lt;br /&gt;
    state_class: measurement&lt;br /&gt;
    accuracy_decimals: 0            # whole centimeters; set 1 if you want 0.1 cm&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      // reuse the meters reading we already compute&lt;br /&gt;
      return id(water_depth).state * 100.0;&lt;br /&gt;
    on_value:&lt;br /&gt;
      then:&lt;br /&gt;
        - lambda: |-&lt;br /&gt;
            id(apply_control).execute();&lt;br /&gt;
&lt;br /&gt;
  # Map 4–20 mA to 0–MAX_DEPTH meters&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: water_depth&lt;br /&gt;
    name: &amp;quot;${friendly_name} Depth&amp;quot;&lt;br /&gt;
    unit_of_measurement: &amp;quot;m&amp;quot;&lt;br /&gt;
    accuracy_decimals: 2&lt;br /&gt;
    update_interval: 1s&lt;br /&gt;
    lambda: |-&lt;br /&gt;
      const float I = id(loop_current).state; // mA&lt;br /&gt;
      float d = (I - 4.0f) / 16.0f * ${max_depth_m}; // ideal meters&lt;br /&gt;
      d += (${zero_offset_cm} / 100.0f);             // apply offset in meters&lt;br /&gt;
      if (d &amp;lt; 0.0f) d = 0.0f;&lt;br /&gt;
      if (d &amp;gt; ${max_depth_m}) d = ${max_depth_m};&lt;br /&gt;
      return d;&lt;br /&gt;
    filters:&lt;br /&gt;
      - throttle: 1s&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
number:&lt;br /&gt;
  - platform: template&lt;br /&gt;
    id: threshold_cm&lt;br /&gt;
    name: &amp;quot;${friendly_name} Threshold (cm)&amp;quot;&lt;br /&gt;
    min_value: 0.0&lt;br /&gt;
    max_value: ${threshold_max_cm}   # must be a number, not a lambda&lt;br /&gt;
    step: 1.0&lt;br /&gt;
    optimistic: true&lt;br /&gt;
    restore_value: true&lt;br /&gt;
    initial_value: 30.0&lt;br /&gt;
    set_action:&lt;br /&gt;
      - lambda: |-&lt;br /&gt;
          id(apply_control).execute();&lt;br /&gt;
&lt;br /&gt;
# Optional: handy extras&lt;br /&gt;
text_sensor:&lt;br /&gt;
  - platform: wifi_info&lt;br /&gt;
    ip_address:&lt;br /&gt;
      name: &amp;quot;${friendly_name} IP&amp;quot;&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
  - id: apply_control&lt;br /&gt;
    mode: restart&lt;br /&gt;
    then:&lt;br /&gt;
      - if:&lt;br /&gt;
          condition:&lt;br /&gt;
            switch.is_on: auto_enable&lt;br /&gt;
          then:&lt;br /&gt;
            - if:&lt;br /&gt;
                condition:&lt;br /&gt;
                  lambda: |-&lt;br /&gt;
                    return id(water_depth_cm).state &amp;gt; id(threshold_cm).state;&lt;br /&gt;
                then:&lt;br /&gt;
                  - if:&lt;br /&gt;
                      condition:&lt;br /&gt;
                        switch.is_off: pump_relay&lt;br /&gt;
                      then:&lt;br /&gt;
                        - logger.log: &amp;quot;Automation: depth &amp;gt; threshold → Relay ON&amp;quot;&lt;br /&gt;
                        - switch.turn_on: pump_relay&lt;br /&gt;
                else:&lt;br /&gt;
                  - if:&lt;br /&gt;
                      condition:&lt;br /&gt;
                        switch.is_on: pump_relay&lt;br /&gt;
                      then:&lt;br /&gt;
                        - logger.log: &amp;quot;Automation: depth ≤ threshold → Relay OFF&amp;quot;&lt;br /&gt;
                        - switch.turn_off: pump_relay&lt;br /&gt;
          else:&lt;br /&gt;
            - logger.log: &amp;quot;Automation disabled — no action taken.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== secrets.yaml ===&lt;br /&gt;
&lt;br /&gt;
Šiame faile aprašoma wifi/mqtt/slaptažodžiai.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
wifi_ap: SSID&lt;br /&gt;
wifi_password: 123456789&lt;br /&gt;
wifi_direct: 123456789&lt;br /&gt;
mqtt_broker: 192.168.1.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Norint, kad veiktų rėlė taip pat reikia sulituoti kartu pinus: '''Relay + 1015'''.&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.50.23.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Kaip matome galime nustatyti kiek CM yra kritinis taškas, žemiau jo relė išsijungia, taip pat galima šią automatiką išjungti arba įjungti. Įjungimo išjungimo būsenos tai pat saugomos po power loss ar atsitiktinių elektros atjungimų, kas yra būtina išlaikant testinumą. Taipogi galima rankiniu būdu valdyti rėlę prieš tai išjungus automatiką. Pagal nutylėjimą pirmam leidimui visos pozicijos yra išjungtos.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9825</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9825"/>
		<updated>2025-10-06T19:58:52Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: /* Sujungimo schema */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dėžutė iš Senukų arba Ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijungiame mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijungiame prie žemės (GND).&lt;br /&gt;
* Prilituojame keramikinį kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išvedame trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikiname, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ccc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.50.23.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Kaip matome galime nustatyti kiek CM yra kritinis taškas, žemiau jo relė išsijungia, taip pat galima šią automatiką išjungti arba įjungti. Įjungimo išjungimo būsenos tai pat saugomos po power loss ar atsitiktinių elektros atjungimų, kas yra būtina išlaikant testinumą. Taipogi galima rankiniu būdu valdyti rėlę prieš tai išjungus automatiką. Pagal nutylėjimą pirmam leidimui visos pozicijos yra išjungtos.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9824</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9824"/>
		<updated>2025-10-06T19:55:25Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dėžutė iš Senukų arba Ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijunkite mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijunkite prie žemės (GND).&lt;br /&gt;
* Prilituokite kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išveskite trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikinkite, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ccc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.50.23.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Kaip matome galime nustatyti kiek CM yra kritinis taškas, žemiau jo relė išsijungia, taip pat galima šią automatiką išjungti arba įjungti. Įjungimo išjungimo būsenos tai pat saugomos po power loss ar atsitiktinių elektros atjungimų, kas yra būtina išlaikant testinumą. Taipogi galima rankiniu būdu valdyti rėlę prieš tai išjungus automatiką. Pagal nutylėjimą pirmam leidimui visos pozicijos yra išjungtos.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9823</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9823"/>
		<updated>2025-10-06T19:54:53Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dežutė iš senukų arba ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijunkite mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijunkite prie žemės (GND).&lt;br /&gt;
* Prilituokite kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išveskite trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikinkite, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ccc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
== Rezultatas ==&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.50.23.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Kaip matome galime nustatyti kiek CM yra kritinis taškas, žemiau jo relė išsijungia, taip pat galima šią automatiką išjungti arba įjungti. Įjungimo išjungimo būsenos tai pat saugomos po power loss ar atsitiktinių elektros atjungimų, kas yra būtina išlaikant testinumą. Taipogi galima rankiniu būdu valdyti rėlę prieš tai išjungus automatiką. Pagal nutylėjimą pirmam leidimui visos pozicijos yra išjungtos.&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.50.23.png&amp;diff=9822</id>
		<title>Vaizdas:Screenshot 2025-10-06 at 22.50.23.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.50.23.png&amp;diff=9822"/>
		<updated>2025-10-06T19:51:19Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9821</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9821"/>
		<updated>2025-10-06T19:48:54Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensoriumi. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą. Taip pat papildomai integracija į MQTT/Home Assistant vandens lygio matavimams centimetrais/metrais.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005006264135776.html Metal Film Resistor 2W 47R] tipas '''2W 47R'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007929336683.html Ceramic Capacitor 104 0.1uF 100NF 50V] tipas 104&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dežutė iš senukų arba ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.34.png|300px]] &lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.20.58.png|300px]]&lt;br /&gt;
[[Vaizdas:Screenshot 2025-10-06 at 22.21.14.png|300px]]&lt;br /&gt;
[[Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp|300px]]&lt;br /&gt;
[[Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
== Sujungimo schema ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
   From Sensor (Blue wire, 4–20 mA −)&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
            ├───────&amp;gt; To ESP8266 ADC0 (A0)   ← sense wire&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
          [===]  ← 47 Ω resistor (shunt)&lt;br /&gt;
          [   ]&lt;br /&gt;
            │&lt;br /&gt;
            │&lt;br /&gt;
           GND  (shared with 24 V PSU and ESP8266)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sujungimas:'''&lt;br /&gt;
* Prijunkite mėlyną sensoriaus laidą prie vienos 50R rezistoriaus kojos.&lt;br /&gt;
* Kitą rezistoriaus koją prijunkite prie žemės (GND).&lt;br /&gt;
* Prilituokite kondensatorių tiesiai per abi rezistoriaus kojas (lygiagrečiai).&lt;br /&gt;
* Nuo mėlyno laido pusės (kur prijungtas prie rezistoriaus) išveskite trumpą laidą į ESP8266 ADC0 (A0) įėjimą.&lt;br /&gt;
* Įsitikinkite, kad maitinimo šaltinis (PSU) ir ESP8266 turi bendrą žemę (GND).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo sujungimas ===&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Vaizdas:Water level scheme in action2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== ESPHome Firmware kodas ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ccc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Flashinimas ==&lt;br /&gt;
&lt;br /&gt;
Pirmiausia reiktų susidiegti esphome python3 modulį:&lt;br /&gt;
 pip3 install esphome&lt;br /&gt;
&lt;br /&gt;
Flashinti reikia per relės UART interfeisą, micro USB interfeisas tam reikalui neskirtas. Pajungiame USB Serial TTL adapterį, sujungiame RX/TX/GND/5V ir galime flashinti, pirmam kartui taip pat būtina užtrumpinti GND + 101 prieš įjungiant įrenginį (randasi tame pačiame UART layoute).&lt;br /&gt;
&lt;br /&gt;
Kompiluojame ir flashiname:&lt;br /&gt;
 python3 -m esphome compile water_level.yaml&lt;br /&gt;
 python3 -m esphome upload water_level.yaml&lt;br /&gt;
&lt;br /&gt;
Vėliau galime flashinti over the air (per tinklą) metodu:&lt;br /&gt;
 python3 -m esphome upload --device DEVICE_IP water_level.yaml&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_scheme_in_action2.png&amp;diff=9820</id>
		<title>Vaizdas:Water level scheme in action2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_scheme_in_action2.png&amp;diff=9820"/>
		<updated>2025-10-06T19:43:45Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_scheme_in_action1.png&amp;diff=9819</id>
		<title>Vaizdas:Water level scheme in action1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Water_level_scheme_in_action1.png&amp;diff=9819"/>
		<updated>2025-10-06T19:43:23Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:0011952_01f-50v-disc-ceramic-capacitor_550-2.jpg&amp;diff=9818</id>
		<title>Vaizdas:0011952 01f-50v-disc-ceramic-capacitor 550-2.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:0011952_01f-50v-disc-ceramic-capacitor_550-2.jpg&amp;diff=9818"/>
		<updated>2025-10-06T19:31:58Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp&amp;diff=9817</id>
		<title>Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:100-pcs-50-ohm-0-25w-metal-film-resistor-1-4w-mfr-emerging-original-imafwyhbdnhmgex3.jpeg-2.webp&amp;diff=9817"/>
		<updated>2025-10-06T19:31:36Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;b&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.21.14.png&amp;diff=9816</id>
		<title>Vaizdas:Screenshot 2025-10-06 at 22.21.14.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.21.14.png&amp;diff=9816"/>
		<updated>2025-10-06T19:24:52Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.20.58.png&amp;diff=9815</id>
		<title>Vaizdas:Screenshot 2025-10-06 at 22.20.58.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.20.58.png&amp;diff=9815"/>
		<updated>2025-10-06T19:24:23Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.20.34.png&amp;diff=9814</id>
		<title>Vaizdas:Screenshot 2025-10-06 at 22.20.34.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Vaizdas:Screenshot_2025-10-06_at_22.20.34.png&amp;diff=9814"/>
		<updated>2025-10-06T19:23:32Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;n&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9813</id>
		<title>Water level QDY30B</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Water_level_QDY30B&amp;diff=9813"/>
		<updated>2025-10-06T19:21:27Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: Naujas puslapis: Vandens lygio matuoklis paremtas '''QDY30B''' sensorium. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vandens lygio matuoklis paremtas '''QDY30B''' sensorium. '''Pagrindinė sprendžiama problema:''' hidroforo išjungimas pasiekus kritinį vandens lygio tašką, t.y kai hidroforo įėimo vamzdis nepasiekia vandens išjungti jam maitinimą.&lt;br /&gt;
&lt;br /&gt;
== Reikalingos medžiagos ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.aliexpress.com/item/1005007266883113.html Submersible Liquid Level Sensor Water Tank Pressure Transmitter 4-20mA 0-10V RS485 Water River Level Transmitter] šiame aprašyme naudojamas '''4-20mA output, 5M range 10m cable'''&lt;br /&gt;
* [https://www.aliexpress.com/item/1005003692342096.html Hi-Link 30W 24 AC DC Single Output Power Supply Module HLK-30M24C]&lt;br /&gt;
* [https://www.aliexpress.com/item/1005001906090486.html ESP8266 WIFI Wireless Relay Module ESP-12F AC 220V DC 5V 12V Power Supply ESP 12F Development Board Remote Control Smart Home] modulis su '''ESP-12F'''&lt;br /&gt;
* Bet kokia elektros paskirstymo hermetinė IP66 dežutė iš senukų arba ermitažo (kad tilptų viskas sugrūsti).&lt;br /&gt;
&lt;br /&gt;
=== Kaip atrodo medžiagos ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[Category:IoT]]&lt;br /&gt;
[[Category:ESP8266]]&lt;br /&gt;
[[Category:Microcontrollers]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9812</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9812"/>
		<updated>2025-09-24T20:14:03Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: /* Tinklas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Docker''' yra atviro kodo projektas skirtas automatizuoti programinės įrangos projektams iš programinės įrangos lygmens konteinerių. Docker konteineriai su failų sistemos palaikymu, sisteminėmis programomis bei bibliotekomis - viskas ko jums reikia paleisti serverį. Garantuotai paleisite tai ką ir turite paleisti, nepriklausant nuo sistemos aplinkos kur tai darote.&lt;br /&gt;
&lt;br /&gt;
Docker suteikia papildomą virtualizacijos, automatikos lygmenį operacijų sistemos lygmenyje pačiame Linux. Docker naudoja Linux resursų izoliavimą [[cgroups]], branduolio vardinius susiejimus, ir [[aufs]] (angl. union-capable filesystem). Tai leidžia nepriklausomai valdyti kelis konteinerius vienoje Linux sistemoje, neužkraunant jos dideliomis apkrovomis kurių reikalauja virtualios mašinos. Linux branduolio vardinių sąsajų palaikymas izoliuoja kaip programos mato pačia operacijų sistemą, izoliuojami procesai, tinklas, vartotojo id, primontuotos failų sistemos, taip pat neprarandamas [[cgroups]] resursų ribojimas (CPU, atmintis, I/O, Tinklas). Nuo docker 0.9 versijos įtraukiama libcontainer biblioteka kuri tiesiogiai bendrauja su virtualizacijos sistemomis esančiomis Linux branduolyje, priedo tai apdorojama per virtualizacijos sąsajas [[libvirt]], [[LXC]] (Linux Containers) ir [[systemd-nspawn]].&lt;br /&gt;
&lt;br /&gt;
== Docker diegimas Debian sistemose ==&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install \&lt;br /&gt;
     apt-transport-https \&lt;br /&gt;
     ca-certificates \&lt;br /&gt;
     curl \&lt;br /&gt;
     gnupg2 \&lt;br /&gt;
     software-properties-common&lt;br /&gt;
 curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -&lt;br /&gt;
 sudo apt-key fingerprint 0EBFCD88&lt;br /&gt;
 sudo add-apt-repository \&lt;br /&gt;
   &amp;quot;deb [arch=amd64] https://download.docker.com/linux/debian \&lt;br /&gt;
   $(lsb_release -cs) \&lt;br /&gt;
   stable&amp;quot;&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install docker-ce&lt;br /&gt;
&lt;br /&gt;
== Komandų vykdymas dockeryje ==&lt;br /&gt;
&lt;br /&gt;
Vykdyti komandas&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; id&lt;br /&gt;
Įjungti shellą&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; bash&lt;br /&gt;
&lt;br /&gt;
== Konkretaus konteinerio logų pravalymas ==&lt;br /&gt;
&lt;br /&gt;
 truncate -s 0 $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
arba&lt;br /&gt;
 echo &amp;quot;&amp;quot; &amp;gt; $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
Kuriant konteinerį logų limito nurodymas&lt;br /&gt;
 docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...&lt;br /&gt;
&lt;br /&gt;
== Tinklas ==&lt;br /&gt;
&lt;br /&gt;
=== Macvlan (ip tame pačiame tinkle) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker network create -d macvlan --subnet=192.1.14.0/24 --ip-range 192.1.14.240/28 --gateway 192.1.14.254 -o parent=eth0 local-lan&lt;br /&gt;
docker run -itd --name Alpine --ip=192.1.14.241 --net=local-lan alpine /bin/sh&lt;br /&gt;
docker exec -it Alpine ip addr&lt;br /&gt;
exec -it Alpine ping 192.1.14.254&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visų tinklų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for n in $(docker network ls --format '{{.Name}}'); do&lt;br /&gt;
  docker network inspect &amp;quot;$n&amp;quot; --format '{{.Name}} {{range .IPAM.Config}}{{.Gateway}} {{end}}'&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Randam kuris tinklas naudoja konkretų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for id in $(docker network ls -q); do&lt;br /&gt;
  gw=&amp;quot;$(docker network inspect &amp;quot;$id&amp;quot; -f '{{range .IPAM.Config}}{{.Gateway}} {{end}}')&amp;quot;&lt;br /&gt;
  if grep -qw '192.168.1.1' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$gw&amp;quot;; then&lt;br /&gt;
    docker network inspect &amp;quot;$id&amp;quot; -f '{{.Name}} ({{.Id}})'&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualizacija]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Tinklas]]&lt;br /&gt;
{{Template:Distributions}}&lt;br /&gt;
[[Category:Docker]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9811</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9811"/>
		<updated>2025-09-24T20:13:47Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Docker''' yra atviro kodo projektas skirtas automatizuoti programinės įrangos projektams iš programinės įrangos lygmens konteinerių. Docker konteineriai su failų sistemos palaikymu, sisteminėmis programomis bei bibliotekomis - viskas ko jums reikia paleisti serverį. Garantuotai paleisite tai ką ir turite paleisti, nepriklausant nuo sistemos aplinkos kur tai darote.&lt;br /&gt;
&lt;br /&gt;
Docker suteikia papildomą virtualizacijos, automatikos lygmenį operacijų sistemos lygmenyje pačiame Linux. Docker naudoja Linux resursų izoliavimą [[cgroups]], branduolio vardinius susiejimus, ir [[aufs]] (angl. union-capable filesystem). Tai leidžia nepriklausomai valdyti kelis konteinerius vienoje Linux sistemoje, neužkraunant jos dideliomis apkrovomis kurių reikalauja virtualios mašinos. Linux branduolio vardinių sąsajų palaikymas izoliuoja kaip programos mato pačia operacijų sistemą, izoliuojami procesai, tinklas, vartotojo id, primontuotos failų sistemos, taip pat neprarandamas [[cgroups]] resursų ribojimas (CPU, atmintis, I/O, Tinklas). Nuo docker 0.9 versijos įtraukiama libcontainer biblioteka kuri tiesiogiai bendrauja su virtualizacijos sistemomis esančiomis Linux branduolyje, priedo tai apdorojama per virtualizacijos sąsajas [[libvirt]], [[LXC]] (Linux Containers) ir [[systemd-nspawn]].&lt;br /&gt;
&lt;br /&gt;
== Docker diegimas Debian sistemose ==&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install \&lt;br /&gt;
     apt-transport-https \&lt;br /&gt;
     ca-certificates \&lt;br /&gt;
     curl \&lt;br /&gt;
     gnupg2 \&lt;br /&gt;
     software-properties-common&lt;br /&gt;
 curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -&lt;br /&gt;
 sudo apt-key fingerprint 0EBFCD88&lt;br /&gt;
 sudo add-apt-repository \&lt;br /&gt;
   &amp;quot;deb [arch=amd64] https://download.docker.com/linux/debian \&lt;br /&gt;
   $(lsb_release -cs) \&lt;br /&gt;
   stable&amp;quot;&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install docker-ce&lt;br /&gt;
&lt;br /&gt;
== Komandų vykdymas dockeryje ==&lt;br /&gt;
&lt;br /&gt;
Vykdyti komandas&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; id&lt;br /&gt;
Įjungti shellą&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; bash&lt;br /&gt;
&lt;br /&gt;
== Konkretaus konteinerio logų pravalymas ==&lt;br /&gt;
&lt;br /&gt;
 truncate -s 0 $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
arba&lt;br /&gt;
 echo &amp;quot;&amp;quot; &amp;gt; $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
Kuriant konteinerį logų limito nurodymas&lt;br /&gt;
 docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...&lt;br /&gt;
&lt;br /&gt;
== Tinklas ==&lt;br /&gt;
&lt;br /&gt;
=== Macvlan (ip tame pačiame tinkle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker network create -d macvlan --subnet=192.1.14.0/24 --ip-range 192.1.14.240/28 --gateway 192.1.14.254 -o parent=eth0 local-lan&lt;br /&gt;
docker run -itd --name Alpine --ip=192.1.14.241 --net=local-lan alpine /bin/sh&lt;br /&gt;
docker exec -it Alpine ip addr&lt;br /&gt;
exec -it Alpine ping 192.1.14.254&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visų tinklų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for n in $(docker network ls --format '{{.Name}}'); do&lt;br /&gt;
  docker network inspect &amp;quot;$n&amp;quot; --format '{{.Name}} {{range .IPAM.Config}}{{.Gateway}} {{end}}'&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Randam kuris tinklas naudoja konkretų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for id in $(docker network ls -q); do&lt;br /&gt;
  gw=&amp;quot;$(docker network inspect &amp;quot;$id&amp;quot; -f '{{range .IPAM.Config}}{{.Gateway}} {{end}}')&amp;quot;&lt;br /&gt;
  if grep -qw '192.168.1.1' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$gw&amp;quot;; then&lt;br /&gt;
    docker network inspect &amp;quot;$id&amp;quot; -f '{{.Name}} ({{.Id}})'&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualizacija]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Tinklas]]&lt;br /&gt;
{{Template:Distributions}}&lt;br /&gt;
[[Category:Docker]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
	<entry>
		<id>https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9810</id>
		<title>Docker</title>
		<link rel="alternate" type="text/html" href="https://wiki.eofnet.lt/w//index.php?title=Docker&amp;diff=9810"/>
		<updated>2025-09-24T19:29:11Z</updated>

		<summary type="html">&lt;p&gt;\dev\null: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Docker''' yra atviro kodo projektas skirtas automatizuoti programinės įrangos projektams iš programinės įrangos lygmens konteinerių. Docker konteineriai su failų sistemos palaikymu, sisteminėmis programomis bei bibliotekomis - viskas ko jums reikia paleisti serverį. Garantuotai paleisite tai ką ir turite paleisti, nepriklausant nuo sistemos aplinkos kur tai darote.&lt;br /&gt;
&lt;br /&gt;
Docker suteikia papildomą virtualizacijos, automatikos lygmenį operacijų sistemos lygmenyje pačiame Linux. Docker naudoja Linux resursų izoliavimą [[cgroups]], branduolio vardinius susiejimus, ir [[aufs]] (angl. union-capable filesystem). Tai leidžia nepriklausomai valdyti kelis konteinerius vienoje Linux sistemoje, neužkraunant jos dideliomis apkrovomis kurių reikalauja virtualios mašinos. Linux branduolio vardinių sąsajų palaikymas izoliuoja kaip programos mato pačia operacijų sistemą, izoliuojami procesai, tinklas, vartotojo id, primontuotos failų sistemos, taip pat neprarandamas [[cgroups]] resursų ribojimas (CPU, atmintis, I/O, Tinklas). Nuo docker 0.9 versijos įtraukiama libcontainer biblioteka kuri tiesiogiai bendrauja su virtualizacijos sistemomis esančiomis Linux branduolyje, priedo tai apdorojama per virtualizacijos sąsajas [[libvirt]], [[LXC]] (Linux Containers) ir [[systemd-nspawn]].&lt;br /&gt;
&lt;br /&gt;
== Docker diegimas Debian sistemose ==&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install \&lt;br /&gt;
     apt-transport-https \&lt;br /&gt;
     ca-certificates \&lt;br /&gt;
     curl \&lt;br /&gt;
     gnupg2 \&lt;br /&gt;
     software-properties-common&lt;br /&gt;
 curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -&lt;br /&gt;
 sudo apt-key fingerprint 0EBFCD88&lt;br /&gt;
 sudo add-apt-repository \&lt;br /&gt;
   &amp;quot;deb [arch=amd64] https://download.docker.com/linux/debian \&lt;br /&gt;
   $(lsb_release -cs) \&lt;br /&gt;
   stable&amp;quot;&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install docker-ce&lt;br /&gt;
&lt;br /&gt;
== Komandų vykdymas dockeryje ==&lt;br /&gt;
&lt;br /&gt;
Vykdyti komandas&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; id&lt;br /&gt;
Įjungti shellą&lt;br /&gt;
 docker exec -it &amp;lt;docker_pavadinimas&amp;gt; bash&lt;br /&gt;
&lt;br /&gt;
== Konkretaus konteinerio logų pravalymas ==&lt;br /&gt;
&lt;br /&gt;
 truncate -s 0 $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
arba&lt;br /&gt;
 echo &amp;quot;&amp;quot; &amp;gt; $(docker inspect --format='&amp;lt;nowiki&amp;gt;{{.LogPath}}&amp;lt;/nowiki&amp;gt;' &amp;lt;container_name_or_id&amp;gt;)&lt;br /&gt;
Kuriant konteinerį logų limito nurodymas&lt;br /&gt;
 docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...&lt;br /&gt;
&lt;br /&gt;
== Tinklas ==&lt;br /&gt;
&lt;br /&gt;
=== Visų tinklų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for n in $(docker network ls --format '{{.Name}}'); do&lt;br /&gt;
  docker network inspect &amp;quot;$n&amp;quot; --format '{{.Name}} {{range .IPAM.Config}}{{.Gateway}} {{end}}'&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Randam kuris tinklas naudoja konkretų gateway ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for id in $(docker network ls -q); do&lt;br /&gt;
  gw=&amp;quot;$(docker network inspect &amp;quot;$id&amp;quot; -f '{{range .IPAM.Config}}{{.Gateway}} {{end}}')&amp;quot;&lt;br /&gt;
  if grep -qw '192.168.1.1' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$gw&amp;quot;; then&lt;br /&gt;
    docker network inspect &amp;quot;$id&amp;quot; -f '{{.Name}} ({{.Id}})'&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Virtualizacija]]&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Tinklas]]&lt;br /&gt;
{{Template:Distributions}}&lt;br /&gt;
[[Category:Docker]]&lt;/div&gt;</summary>
		<author><name>\dev\null</name></author>
	</entry>
</feed>