diff --git a/agent/jarvis-ha-poller.py b/agent/jarvis-ha-poller.py index 372859b..d5c1015 100644 --- a/agent/jarvis-ha-poller.py +++ b/agent/jarvis-ha-poller.py @@ -175,7 +175,7 @@ def fetch_ha_states(cfg: dict) -> list: dt = datetime.fromisoformat(lc.replace("Z", "+00:00")) lc = dt.astimezone(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") except Exception: - lc = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + lc = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") entities.append({ "entity_id": entity_id, @@ -194,13 +194,11 @@ def main(): heartbeat_every = int(cfg.get("heartbeat_every", 10)) api_key = state.get("api_key", "") - if not api_key: + while not api_key: api_key = register(cfg, state) if not api_key: log("Could not register. Retrying in 60s...") time.sleep(60) - main() - return headers = {"X-Agent-Key": api_key} last_push = 0 @@ -229,6 +227,7 @@ def main(): last_push = now else: log("No HA entities fetched (HA down or token invalid?)") + last_push = now time.sleep(heartbeat_every) diff --git a/agent/pve1-probes/jarvis-netscan.sh b/agent/pve1-probes/jarvis-netscan.sh index 1ab6c66..57ecbab 100644 --- a/agent/pve1-probes/jarvis-netscan.sh +++ b/agent/pve1-probes/jarvis-netscan.sh @@ -4,7 +4,11 @@ JARVIS_URL="http://10.48.200.211" JARVIS_HOST="jarvis.orbishosting.com" -REG_KEY="f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518" +REG_KEY=$(cat /etc/jarvis-agent/reg-key 2>/dev/null) +if [ -z "$REG_KEY" ]; then + echo "$(date): ERROR: /etc/jarvis-agent/reg-key not found" >&2 + exit 1 +fi SUBNET="10.48.200.0/24" TMPFILE=$(mktemp) diff --git a/agent/pve1-probes/jarvis-phone-probe.sh b/agent/pve1-probes/jarvis-phone-probe.sh index b2ea9c3..936fe70 100644 --- a/agent/pve1-probes/jarvis-phone-probe.sh +++ b/agent/pve1-probes/jarvis-phone-probe.sh @@ -5,7 +5,11 @@ JARVIS_URL="http://10.48.200.211" JARVIS_HOST="jarvis.orbishosting.com" -REG_KEY="f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518" +REG_KEY=$(cat /etc/jarvis-agent/reg-key 2>/dev/null) +if [ -z "$REG_KEY" ]; then + echo "$(date): ERROR: /etc/jarvis-agent/reg-key not found" >&2 + exit 1 +fi FUSION_HOST="134.209.72.226" # IP|alias|extension(none=skip SIP check)|mac @@ -21,19 +25,17 @@ PHONES=( REG_OUTPUT=$(ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -o BatchMode=yes \ root@$FUSION_HOST "fs_cli -x 'show registrations'" 2>/dev/null || echo "") -DEVICES="[" -FIRST=1 +# Collect results as TSV, delegate JSON building to python3 to avoid injection +RESULTS="" for PHONE in "${PHONES[@]}"; do IFS='|' read -r IP ALIAS EXT MAC <<< "$PHONE" - # Ping probe if ping -c 1 -W 2 "$IP" > /dev/null 2>&1; then STATUS="online" else STATUS="offline" fi - # SIP check — skip for external phones (ext=none) if [ "$EXT" = "none" ]; then SIP="external" elif [ -n "$REG_OUTPUT" ] && echo "$REG_OUTPUT" | grep -q "^${EXT},"; then @@ -42,15 +44,31 @@ for PHONE in "${PHONES[@]}"; do SIP="unregistered" fi - [ $FIRST -eq 0 ] && DEVICES+="," - DEVICES+="{\"ip\":\"$IP\",\"alias\":\"$ALIAS\",\"mac\":\"$MAC\",\"vendor\":\"Yealink\",\"status\":\"$STATUS\",\"sip_status\":\"$SIP\",\"extension\":\"$EXT\"}" - FIRST=0 + RESULTS="${RESULTS}${IP}\t${ALIAS}\t${MAC}\t${STATUS}\t${SIP}\t${EXT}\n" done -DEVICES+="]" + +JSON=$(printf "%b" "$RESULTS" | python3 -c " +import sys, json +devices = [] +for line in sys.stdin: + line = line.rstrip('\n') + if not line: + continue + parts = line.split('\t') + if len(parts) < 6: + continue + ip, alias, mac, status, sip, ext = parts[:6] + devices.append({ + 'ip': ip, 'alias': alias, 'mac': mac, + 'vendor': 'Yealink', 'status': status, + 'sip_status': sip, 'extension': ext, + }) +print(json.dumps({'devices': devices})) +") curl -sk --max-time 10 \ -X POST "$JARVIS_URL/api/netscan" \ -H "Host: $JARVIS_HOST" \ -H "Content-Type: application/json" \ -H "X-Registration-Key: $REG_KEY" \ - -d "{\"devices\":$DEVICES}" > /dev/null 2>&1 + -d "$JSON" > /dev/null 2>&1 diff --git a/agent/pve1-probes/jarvis-ping-probe.py b/agent/pve1-probes/jarvis-ping-probe.py index 620faad..72e68f8 100644 --- a/agent/pve1-probes/jarvis-ping-probe.py +++ b/agent/pve1-probes/jarvis-ping-probe.py @@ -93,8 +93,7 @@ def main(): status = "online" if alive else "offline" print(f"{agent_id} ({ip}): {status}", flush=True) heartbeat(agent_id, api_key, alive) - if alive: - update_status(agent_id, api_key, status) + update_status(agent_id, api_key, status) if __name__ == "__main__": main() diff --git a/api/endpoints/agent.php b/api/endpoints/agent.php index f768250..32a2132 100644 --- a/api/endpoints/agent.php +++ b/api/endpoints/agent.php @@ -111,7 +111,8 @@ switch ($agentAction) { // ── HEARTBEAT ──────────────────────────────────────────────────────────── case 'heartbeat': - update_agent_seen($agent['agent_id'], 'online', trim($data['version'] ?? '') ?: null); + $hbStatus = in_array($data['status'] ?? '', ['online','offline']) ? $data['status'] : 'online'; + update_agent_seen($agent['agent_id'], $hbStatus, trim($data['version'] ?? '') ?: null); // Return any pending commands for this agent $commands = JarvisDB::query( diff --git a/api/endpoints/facts_collector.php b/api/endpoints/facts_collector.php index 32841c7..4b9bcc9 100644 --- a/api/endpoints/facts_collector.php +++ b/api/endpoints/facts_collector.php @@ -181,7 +181,7 @@ function collect_all(): array { $results['sites'] = 'skipped (fresh)'; } else try { $sites = [ - "jarvis" => "https://jarvis.orbishosting.com", + "jarvis" => "http://127.0.0.1", 'tomsjavajive' => 'https://tomsjavajive.com', 'epictravelexp'=> 'https://epictravelexpeditions.com', 'parkersling' => 'https://parkerslingshotrentals.com', diff --git a/public_html/admin/index.php b/public_html/admin/index.php index c76d3e9..a440ce7 100644 --- a/public_html/admin/index.php +++ b/public_html/admin/index.php @@ -242,7 +242,9 @@ if ($action) { $search = strtolower(trim($_GET['search'] ?? '')); $skipDomains = ['sensor','binary_sensor','button','update','select','number', 'device_tracker','event','image','person','zone','tts','conversation', - 'assist_satellite','input_button']; + 'assist_satellite','input_button','media_player','scene','water_heater', + 'alarm_control_panel','automation','script','calendar','notify', + 'weather','camera','siren','remote','todo','lawn_mower']; $skipKeywords = ['pre_release','_record','_ftp_','_push_','_hub_ringtone', '_siren_on','_email_on','_manual_record','_infrared_', 'do_not_disturb','matter_server','zerotier','mariadb',