Надо прееделать на функционал, там формируется список устройст строится таблица, потом при клике - появляются кнопки и дополнительные функции
<?php
$dispensers = [
    ['name' => 'Бюро пропусков', 'ip' => '192.168.1.14'],
    ['name' => 'Диспенсер 2', 'ip' => '192.168.1.15'],
    ['name' => 'КПП2 - Диспенсер 1-1', 'ip' => '192.168.1.181:80'],
	['name' => 'КПП2 - Диспенсер 1-2', 'ip' => '192.168.1.181:82'],
    ['name' => 'КПП2 - Диспенсер 2', 'ip' => '192.168.1.182'],
];
?>
  <style>
    body { font-family: Arial, sans-serif; margin: 30px; }
    #result { white-space: pre; background: #f4f4f4; padding: 10px; border-radius: 5px; }
    button { margin: 5px 0; }
    select { margin-bottom: 10px; }
  </style>
<?php
/*
	<button id="allStatusBtn" style="margin-bottom:15px;">Общий статус всех диспенсеров</button>
	*/
	?>
	<div id="allStatus"></div>

  <h2>Диспенсеры</h2>
  	<?php /*
  <select id="dispenserSelect"></select>
  <div id="controls" style="margin-top: 20px;">
	  <button data-api="4" disabled>Статус диспенсера</button>
	  <button data-api="3" disabled>Перезагрузить</button>
	  <button data-api="4/5" disabled>Сброс карты</button>
	  <button data-api="1" disabled>Лог файлы</button>


	
		<button data-api="4">Статус диспенсера</button>
	<button data-api="3">Перезагрузить</button>
	<button data-api="4/5">Сброс карты</button>
    <button data-api="1">Лог файлы</button>

	 <button data-api="2">Последняя карта</button>
    <button data-api="4/2">Подвинуть карту в позицию</button>
    <button data-api="4/3">Подвинуть карту во 2 позицию</button>
    <button data-api="4/4">Вытащить наружу</button>
    
    <button data-api="4/6">Проверка датчиков</button>
	*/
	?>
  </div>
  <div id="dispenserStatus"></div>

  <h3>Результат</h3>
  <div id="result">Выберите диспенсер и действие.</div>

  <script>
    const controls = document.getElementById('controls');
	<?php 
	/*
	const select = document.getElementById('dispenserSelect');

	select.addEventListener('change', function() {
	  // Получаем все кнопки внутри блока controls
	  const buttons = controls.querySelectorAll('button');
	  // Если выбран какой-то диспенсер (value не пустое)
	  if (select.value) {
		buttons.forEach(btn => btn.disabled = false);
	  } else {
		buttons.forEach(btn => btn.disabled = true);
	  }
	});

	// Для начального состояния (если select уже выбран)
	window.addEventListener('DOMContentLoaded', function() {
	  const event = new Event('change');
	  select.dispatchEvent(event);
	});
	*/ ?>
    const DISPENSERS = <?php echo json_encode($dispensers, JSON_UNESCAPED_UNICODE); ?>;

   
    /*
    DISPENSERS.forEach((d) => {
      const opt = document.createElement('option');
      opt.value = d.ip;
      opt.textContent = `${d.name}`;
      select.appendChild(opt);
    });
	*/
    document.getElementById('controls').addEventListener('click', async (e) => {
      if (e.target.tagName !== 'BUTTON') return;
      const ip = select.value;
      const api = e.target.getAttribute('data-api');
      const url = `/dspp.php?q=1&ip=${encodeURIComponent(ip)}&api=${encodeURIComponent(api)}`;
     
      try {
        const resp = await fetch(url, { method: 'GET' });
        if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
        const data = await resp.json();
        showResult(formatResponse(data, api));
      } catch (err) {
        showResult('Ошибка: ' + err);
      }
    });
	
    function formatResponse(data, api) {
	  if (api === "1" && data.f && data.f.txt) {
		  return "Лог:\n" + data.f.txt.slice().reverse().join('\n');
	  }
      if (api === "2" && data.f && data.f.card) {
        return `Последняя карта: ${data.f.card}`;
      }
      if ((api === "3" || api === "4") && data.f) {
		renderDispenserStatus(data.f); 
        return "Статус:\n" + JSON.stringify(data.f, null, 2);
      }
      if (/^4\/[2-6]$/.test(api) && data.f && typeof data.f.status !== "undefined") {
        return `Статус операции: ${data.f.status ? "Успех" : "Ошибка"}`;
      }
      return JSON.stringify(data, null, 2);
    }

    function renderDispenserStatus(status) {
		  var container = document.getElementById('dispenserStatus');
		  if (!status) {
			container.innerHTML = '';
			return;
		  }
		  var html = '';


		  html += '<div style="margin-bottom:8px;"><b>Диспенсер:</b> ' +
			(status.dispenser ? '<span style="color:green;">Работает</span>' : '<span style="color:gray;">Остановлен</span>') +
			'</div>';

		  html += indicator(status.dispenser, 'Работает');
		  html += indicator(status.dispenser_work, 'В работе', 'blue');
		  html += indicator(status.keyboard, 'Клавиатура');
		  html += indicator(status.scanner, 'Сканер');

		 
		  html += '<div style="margin:8px 0 0 0;">' +
			'<span style="margin-right:20px;">Сброшено карт: <b>' + (status.dispenser_break || 0) + '</b></span>' +
			'<span>Выдано карт: <b>' + (status.dispenser_send || 0) + '</b></span>' +
			'</div>';

		 
		  html += '<div style="margin:8px 0 0 0;">Карта в сканере: <b>' + (status.scanner_card || '-') + '</b></div>';

	
		  html += '<div style="margin-top:8px;">';
		  html += indicator(status.dispenser_param.command_error, 'Ошибка команды', 'red');
		  html += indicator(status.dispenser_param.dispense_error, 'Ошибка выдачи', 'red');
		  html += indicator(status.dispenser_param.jammed, 'Зажевало', 'red');
		  html += indicator(status.dispenser_param.empty, 'Пусто', 'orange');
		  html += indicator(status.dispenser_param.pre_empty, 'Почти пусто', 'gold');
		  html += indicator(status.dispenser_param.preparing_fails, 'Ошибка подготовки', 'red');
		  html += '</div>';

		
		  html += '<div style="margin-top:8px;">';
		  html += indicator(status.dispenser_param.captured, 'Карта захвачена', 'blue');
		  html += indicator(status.dispenser_param.capturing, 'Захват карты', 'blue');
		  html += indicator(status.dispenser_param.keep, 'Карта удерживается', 'blue');
		  html += indicator(status.dispenser_param.no_captured, 'Нет захвата', 'gray');
		  html += indicator(status.dispenser_param.dispensing, 'Выдача', 'green');
		  html += indicator(status.dispenser_param.preparing, 'Подготовка', 'green');
		  html += indicator(status.dispenser_param.overlapped, 'Наложение', 'red');
		  html += '</div>';

		  html += '<div style="margin-top:8px;">Датчики: ';
		  html += indicator(status.dispenser_param.s1, 'S1', 'green', '#eee');
		  html += indicator(status.dispenser_param.s2, 'S2', 'green', '#eee');
		  html += indicator(status.dispenser_param.s3, 'S3', 'green', '#eee');
		  html += '</div>';

		  container.innerHTML = '<div style="padding:10px 0 10px 0;">' + html + '</div>';
		}

		function indicator(val, label, colorOn, colorOff) {
		  colorOn = colorOn || 'green';
		  colorOff = colorOff || 'gray';
		  return '<span style="display:inline-block;margin:2px 8px 2px 0;">' +
			'<span style="display:inline-block;width:14px;height:14px;border-radius:50%;background:' + (val ? colorOn : colorOff) + ';vertical-align:middle;margin-right:4px;border:1px solid #888"></span>' +
			'<span style="vertical-align:middle;">' + label + '</span>' +
		  '</span>';
		}


    function showResult(text) {
      document.getElementById('result').textContent = text;
    }
	  <?php 
	/*
	document.getElementById('allStatusBtn').addEventListener('click', async function() {
  var container = document.getElementById('allStatus');
  container.innerHTML = 'Загрузка...';
  try {
    var resp = await fetch('/dspp.php?q=2');
    if (!resp.ok) throw new Error('HTTP ' + resp.status);
    var data = await resp.json();
    container.innerHTML = renderAllStatus(data);
  } catch (err) {
    container.innerHTML = 'Ошибка: ' + err;
  }
});
*/
?>

function renderAllStatus(data) {
	  if (!Array.isArray(data)) return 'Нет данных';
	  var html = '<table border="1" cellpadding="6" style="border-collapse:collapse;"><tr>' +
		'<th>Диспенсер</th><th>Статус</th><th>Карта</th><th>Пусто</th><th>Почти пусто</th><th>Сброшено</th><th>Выдано</th></tr>';
	  data.forEach(function(d) {
		var st = d.status;
		var ok = st && st.dispenser ? '<span style="color:green;">Работает</span>' : '<span style="color:red;">Нет</span>';
		var card = st && st.scanner_card ? st.scanner_card : '-';
		var empty = st && st.dispenser_param && st.dispenser_param.empty ? '<span style="color:red;">Пусто</span>' : '';
		var pre_empty = st && st.dispenser_param && st.dispenser_param.pre_empty ? '<span style="color:orange;">Почти пусто</span>' : '';
		var dropped = st && typeof st.dispenser_break !== 'undefined' ? st.dispenser_break : '-';
		var dispensed = st && typeof st.dispenser_send !== 'undefined' ? st.dispenser_send : '-';
		html += '<tr>' +
		  '<td><a href="#" class="dispenser-link" data-ip="'+d.ip+'">'+d.name+'</a></td>' +
		  '<td>' + (d.error ? '<span style="color:red;">Нет связи</span>' : ok) + '</td>' +
		  '<td>' + card + '</td>' +
		  '<td>' + (empty || '-') + '</td>' +
		  '<td>' + (pre_empty || '-') + '</td>' +
		  '<td>' + dropped + '</td>' +
		  '<td>' + dispensed + '</td>' +
		  '</tr>';
	  });
	  html += '</table>';
	  return html;
	}
	document.addEventListener('click', function(e) {
	  if (e.target.classList.contains('dispenser-link')) {
		e.preventDefault();
		const ip = e.target.getAttribute('data-ip');
		// Установить select на нужный ip
		select.value = ip;
		// Активировать кнопки
		const buttons = controls.querySelectorAll('button');
		buttons.forEach(btn => btn.disabled = false);
		// Можно сразу вызвать обновление статуса, если нужно:
		// document.querySelector('button[data-api="4"]').click();
	  }
	});
	async function statusall() {
	  var container = document.getElementById('allStatus');
	  container.innerHTML = 'Загрузка...';
	  try {
		var resp = await fetch('/dspp.php?q=2');
		if (!resp.ok) throw new Error('HTTP ' + resp.status);
		var data = await resp.json();
		container.innerHTML = renderAllStatus(data);
	  } catch (err) {
		container.innerHTML = 'Ошибка: ' + err;
	  }
	  setTimeout(statusall, 60000);
	}
	statusall();
  </script>