From 681830813b7272ca9b0c2fbcc10376d9d515fd8f Mon Sep 17 00:00:00 2001
From: raoulvdberge <raoulvdberge@gmail.com>
Date: Sun, 17 Nov 2024 09:49:24 +0100
Subject: [PATCH 1/2] refactor: autocrafting monitor now delegates to network

---
 .../status/TaskStatusProvider.java            |  2 +
 .../common/AbstractModInitializer.java        |  3 +-
 ...tractAutocraftingMonitorContainerMenu.java | 41 +++++------
 .../monitor/AutocraftingMonitor.java          |  9 +++
 .../AutocraftingMonitorBlockEntity.java       | 70 ++++++++++++++++---
 .../AutocraftingMonitorContainerMenu.java     | 20 +-----
 .../monitor/AutocraftingMonitorScreen.java    |  2 +-
 .../monitor/AutocraftingMonitorWatcher.java   |  2 +-
 .../monitor/TaskStatusProviderImpl.java       |  7 +-
 .../grid/AbstractGridContainerMenu.java       | 20 ++----
 .../AutocraftingNetworkComponent.java         |  3 +-
 .../test/fixtures/FakeTaskStatusProvider.java | 40 +++++++++++
 .../test/fixtures/NetworkTestFixtures.java    |  2 +-
 .../AutocraftingNetworkComponentImpl.java     | 39 +++++++++++
 .../AutocraftingNetworkComponentImplTest.java |  3 +-
 15 files changed, 190 insertions(+), 73 deletions(-)
 create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
 create mode 100644 refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/FakeTaskStatusProvider.java

diff --git a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/status/TaskStatusProvider.java b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/status/TaskStatusProvider.java
index a74424707..8fbc08337 100644
--- a/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/status/TaskStatusProvider.java
+++ b/refinedstorage-autocrafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/status/TaskStatusProvider.java
@@ -17,4 +17,6 @@ public interface TaskStatusProvider {
     void cancel(TaskId taskId);
 
     void cancelAll();
+
+    void testUpdate();
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
index 454a34aa4..5f7f8d8ee 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
@@ -28,6 +28,7 @@
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorBlockEntity;
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorData;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.TaskStatusProviderImpl;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridBlockEntity;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridData;
@@ -276,7 +277,7 @@ private void registerNetworkComponents() {
         );
         RefinedStorageApi.INSTANCE.getNetworkComponentMapFactory().addFactory(
             AutocraftingNetworkComponent.class,
-            network -> new AutocraftingNetworkComponentImpl()
+            network -> new AutocraftingNetworkComponentImpl(new TaskStatusProviderImpl())
         );
     }
 
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AbstractAutocraftingMonitorContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AbstractAutocraftingMonitorContainerMenu.java
index cf639c9d5..88fc8fe48 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AbstractAutocraftingMonitorContainerMenu.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AbstractAutocraftingMonitorContainerMenu.java
@@ -3,7 +3,6 @@
 import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
 import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
 import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
-import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
 import com.refinedmods.refinedstorage.common.support.AbstractBaseContainerMenu;
 import com.refinedmods.refinedstorage.common.support.packet.c2s.C2SPackets;
 import com.refinedmods.refinedstorage.common.support.packet.s2c.S2CPackets;
@@ -25,7 +24,7 @@ public abstract class AbstractAutocraftingMonitorContainerMenu extends AbstractB
     private final List<TaskStatus.TaskInfo> tasks;
     private final List<TaskStatus.TaskInfo> tasksView;
     @Nullable
-    private final TaskStatusProvider taskStatusProvider;
+    private final AutocraftingMonitor autocraftingMonitor;
     private final Player player;
 
     @Nullable
@@ -46,38 +45,40 @@ protected AbstractAutocraftingMonitorContainerMenu(final MenuType<?> menuType,
         this.tasks = data.statuses().stream().map(TaskStatus::info).collect(Collectors.toList());
         this.tasksView = Collections.unmodifiableList(tasks);
         this.currentTaskId = data.statuses().isEmpty() ? null : data.statuses().getFirst().info().id();
-        this.taskStatusProvider = null;
+        this.autocraftingMonitor = null;
         this.active = data.active();
         this.player = playerInventory.player;
     }
 
-    protected AbstractAutocraftingMonitorContainerMenu(final MenuType<?> menuType,
-                                                       final int syncId,
-                                                       final Player player,
-                                                       final TaskStatusProvider taskStatusProvider) {
+    AbstractAutocraftingMonitorContainerMenu(final MenuType<?> menuType,
+                                             final int syncId,
+                                             final Player player,
+                                             final AutocraftingMonitor autocraftingMonitor) {
         super(menuType, syncId);
         this.statusByTaskId = Collections.emptyMap();
         this.tasks = Collections.emptyList();
         this.tasksView = Collections.emptyList();
         this.currentTaskId = null;
-        this.taskStatusProvider = taskStatusProvider;
+        this.autocraftingMonitor = autocraftingMonitor;
         this.player = player;
-        taskStatusProvider.addListener(this);
+        this.autocraftingMonitor.addListener(this);
+        this.autocraftingMonitor.addWatcher(this);
     }
 
     @Override
     public void removed(final Player removedPlayer) {
         super.removed(removedPlayer);
-        if (taskStatusProvider != null) {
-            taskStatusProvider.removeListener(this);
+        if (autocraftingMonitor != null) {
+            autocraftingMonitor.removeListener(this);
+            autocraftingMonitor.removeWatcher(this);
         }
     }
 
     @Override
     public void broadcastChanges() {
         super.broadcastChanges();
-        if (taskStatusProvider instanceof TaskStatusProviderImpl taskStatusProviderImpl) {
-            taskStatusProviderImpl.testTick();
+        if (autocraftingMonitor != null) {
+            autocraftingMonitor.testUpdate();
         }
     }
 
@@ -115,7 +116,7 @@ void loadCurrentTask() {
 
     @Override
     public void taskStatusChanged(final TaskStatus status) {
-        if (taskStatusProvider != null && player instanceof ServerPlayer serverPlayer) {
+        if (autocraftingMonitor != null && player instanceof ServerPlayer serverPlayer) {
             S2CPackets.sendAutocraftingMonitorTaskStatusChanged(serverPlayer, status);
             return;
         }
@@ -124,7 +125,7 @@ public void taskStatusChanged(final TaskStatus status) {
 
     @Override
     public void taskRemoved(final TaskId id) {
-        if (taskStatusProvider != null && player instanceof ServerPlayer serverPlayer) {
+        if (autocraftingMonitor != null && player instanceof ServerPlayer serverPlayer) {
             S2CPackets.sendAutocraftingMonitorTaskRemoved(serverPlayer, id);
             return;
         }
@@ -141,7 +142,7 @@ public void taskRemoved(final TaskId id) {
 
     @Override
     public void taskAdded(final TaskStatus status) {
-        if (taskStatusProvider != null && player instanceof ServerPlayer serverPlayer) {
+        if (autocraftingMonitor != null && player instanceof ServerPlayer serverPlayer) {
             S2CPackets.sendAutocraftingMonitorTaskAdded(serverPlayer, status);
             return;
         }
@@ -157,8 +158,8 @@ public void taskAdded(final TaskStatus status) {
     }
 
     public void cancelTask(final TaskId taskId) {
-        if (taskStatusProvider != null) {
-            taskStatusProvider.cancel(taskId);
+        if (autocraftingMonitor != null) {
+            autocraftingMonitor.cancel(taskId);
         }
     }
 
@@ -169,8 +170,8 @@ void cancelCurrentTask() {
     }
 
     public void cancelAllTasks() {
-        if (taskStatusProvider != null) {
-            taskStatusProvider.cancelAll();
+        if (autocraftingMonitor != null) {
+            autocraftingMonitor.cancelAll();
         } else {
             C2SPackets.sendAutocraftingMonitorCancelAll();
         }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
new file mode 100644
index 000000000..3bb5b3259
--- /dev/null
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
@@ -0,0 +1,9 @@
+package com.refinedmods.refinedstorage.common.autocrafting.monitor;
+
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
+
+interface AutocraftingMonitor extends TaskStatusProvider {
+    void addWatcher(AutocraftingMonitorWatcher watcher);
+
+    void removeWatcher(AutocraftingMonitorWatcher watcher);
+}
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
index b9759b6f6..ddd57f10d 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
@@ -1,5 +1,10 @@
 package com.refinedmods.refinedstorage.common.autocrafting.monitor;
 
+import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
+import com.refinedmods.refinedstorage.api.network.Network;
+import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent;
 import com.refinedmods.refinedstorage.api.network.impl.node.SimpleNetworkNode;
 import com.refinedmods.refinedstorage.common.Platform;
 import com.refinedmods.refinedstorage.common.content.BlockEntities;
@@ -8,7 +13,10 @@
 import com.refinedmods.refinedstorage.common.support.containermenu.NetworkNodeExtendedMenuProvider;
 import com.refinedmods.refinedstorage.common.support.network.AbstractBaseNetworkNodeContainerBlockEntity;
 
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 import net.minecraft.core.BlockPos;
@@ -21,7 +29,7 @@
 import net.minecraft.world.level.block.state.BlockState;
 
 public class AutocraftingMonitorBlockEntity extends AbstractBaseNetworkNodeContainerBlockEntity<SimpleNetworkNode>
-    implements NetworkNodeExtendedMenuProvider<AutocraftingMonitorData> {
+    implements NetworkNodeExtendedMenuProvider<AutocraftingMonitorData>, AutocraftingMonitor {
     private final Set<AutocraftingMonitorWatcher> watchers = new HashSet<>();
 
     public AutocraftingMonitorBlockEntity(final BlockPos pos, final BlockState state) {
@@ -30,14 +38,6 @@ public AutocraftingMonitorBlockEntity(final BlockPos pos, final BlockState state
         ));
     }
 
-    void addWatcher(final AutocraftingMonitorWatcher watcher) {
-        watchers.add(watcher);
-    }
-
-    void removeWatcher(final AutocraftingMonitorWatcher watcher) {
-        watchers.remove(watcher);
-    }
-
     @Override
     protected void activenessChanged(final boolean newActive) {
         super.activenessChanged(newActive);
@@ -57,7 +57,7 @@ protected boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState
 
     @Override
     public AutocraftingMonitorData getMenuData() {
-        return new AutocraftingMonitorData(new TaskStatusProviderImpl().getStatuses(), mainNetworkNode.isActive());
+        return new AutocraftingMonitorData(getStatuses(), mainNetworkNode.isActive());
     }
 
     @Override
@@ -67,6 +67,54 @@ public StreamEncoder<RegistryFriendlyByteBuf, AutocraftingMonitorData> getMenuCo
 
     @Override
     public AbstractContainerMenu createMenu(final int syncId, final Inventory inventory, final Player player) {
-        return new AutocraftingMonitorContainerMenu(syncId, player, new TaskStatusProviderImpl(), this);
+        return new AutocraftingMonitorContainerMenu(syncId, player, this);
+    }
+
+    private Optional<AutocraftingNetworkComponent> getAutocrafting() {
+        final Network network = mainNetworkNode.getNetwork();
+        if (network == null) {
+            return Optional.empty();
+        }
+        return Optional.of(network.getComponent(AutocraftingNetworkComponent.class));
+    }
+
+    @Override
+    public List<TaskStatus> getStatuses() {
+        return getAutocrafting().map(AutocraftingNetworkComponent::getStatuses).orElse(Collections.emptyList());
+    }
+
+    @Override
+    public void addListener(final TaskStatusListener listener) {
+        getAutocrafting().ifPresent(autocrafting -> autocrafting.addListener(listener));
+    }
+
+    @Override
+    public void removeListener(final TaskStatusListener listener) {
+        getAutocrafting().ifPresent(autocrafting -> autocrafting.removeListener(listener));
+    }
+
+    @Override
+    public void cancel(final TaskId taskId) {
+        getAutocrafting().ifPresent(autocrafting -> autocrafting.cancel(taskId));
+    }
+
+    @Override
+    public void cancelAll() {
+        getAutocrafting().ifPresent(AutocraftingNetworkComponent::cancelAll);
+    }
+
+    @Override
+    public void testUpdate() {
+        getAutocrafting().ifPresent(AutocraftingNetworkComponent::testUpdate);
+    }
+
+    @Override
+    public void addWatcher(final AutocraftingMonitorWatcher watcher) {
+        watchers.add(watcher);
+    }
+
+    @Override
+    public void removeWatcher(final AutocraftingMonitorWatcher watcher) {
+        watchers.remove(watcher);
     }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorContainerMenu.java
index e6d29160f..46a08b825 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorContainerMenu.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorContainerMenu.java
@@ -1,48 +1,30 @@
 package com.refinedmods.refinedstorage.common.autocrafting.monitor;
 
-import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
 import com.refinedmods.refinedstorage.common.content.Menus;
 import com.refinedmods.refinedstorage.common.support.RedstoneMode;
 import com.refinedmods.refinedstorage.common.support.containermenu.ClientProperty;
 import com.refinedmods.refinedstorage.common.support.containermenu.PropertyTypes;
 import com.refinedmods.refinedstorage.common.support.containermenu.ServerProperty;
 
-import javax.annotation.Nullable;
-
 import net.minecraft.world.entity.player.Inventory;
 import net.minecraft.world.entity.player.Player;
 
 public class AutocraftingMonitorContainerMenu extends AbstractAutocraftingMonitorContainerMenu {
-    @Nullable
-    private final AutocraftingMonitorBlockEntity autocraftingMonitor;
-
     public AutocraftingMonitorContainerMenu(final int syncId,
                                             final Inventory playerInventory,
                                             final AutocraftingMonitorData data) {
         super(Menus.INSTANCE.getAutocraftingMonitor(), syncId, playerInventory, data);
         registerProperty(new ClientProperty<>(PropertyTypes.REDSTONE_MODE, RedstoneMode.IGNORE));
-        this.autocraftingMonitor = null;
     }
 
     AutocraftingMonitorContainerMenu(final int syncId,
                                      final Player player,
-                                     final TaskStatusProvider taskStatusProvider,
                                      final AutocraftingMonitorBlockEntity autocraftingMonitor) {
-        super(Menus.INSTANCE.getAutocraftingMonitor(), syncId, player, taskStatusProvider);
+        super(Menus.INSTANCE.getAutocraftingMonitor(), syncId, player, autocraftingMonitor);
         registerProperty(new ServerProperty<>(
             PropertyTypes.REDSTONE_MODE,
             autocraftingMonitor::getRedstoneMode,
             autocraftingMonitor::setRedstoneMode
         ));
-        this.autocraftingMonitor = autocraftingMonitor;
-        autocraftingMonitor.addWatcher(this);
-    }
-
-    @Override
-    public void removed(final Player removedPlayer) {
-        super.removed(removedPlayer);
-        if (autocraftingMonitor != null) {
-            autocraftingMonitor.removeWatcher(this);
-        }
     }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorScreen.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorScreen.java
index d7341a5cc..9ac2e2d80 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorScreen.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorScreen.java
@@ -326,7 +326,7 @@ private void renderItemText(final GuiGraphics graphics,
                                 final int y) {
         int yy = y;
         if (item.stored() > 0) {
-            renderItemText(graphics, "stored", rendering, x, yy, item.missing());
+            renderItemText(graphics, "stored", rendering, x, yy, item.stored());
             yy += 7;
         }
         if (item.missing() > 0) {
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorWatcher.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorWatcher.java
index 7ee80632c..56c3c0dca 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorWatcher.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorWatcher.java
@@ -1,6 +1,6 @@
 package com.refinedmods.refinedstorage.common.autocrafting.monitor;
 
 @FunctionalInterface
-interface AutocraftingMonitorWatcher {
+public interface AutocraftingMonitorWatcher {
     void activeChanged(boolean active);
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/TaskStatusProviderImpl.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/TaskStatusProviderImpl.java
index fc96c9b99..76aeb33fc 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/TaskStatusProviderImpl.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/TaskStatusProviderImpl.java
@@ -18,7 +18,7 @@
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.Items;
 
-class TaskStatusProviderImpl implements TaskStatusProvider {
+public class TaskStatusProviderImpl implements TaskStatusProvider {
     private static final Item[] ITEM_SET = new Item[] {
         Items.DIRT,
         Items.DIAMOND,
@@ -66,12 +66,13 @@ public void cancelAll() {
         copy.forEach(s -> listeners.forEach(l -> l.taskRemoved(s.info().id())));
     }
 
-    void testTick() {
+    @Override
+    public void testUpdate() {
         if (ticks++ % 10 != 0) {
             return;
         }
         final int chance = r.nextInt(100);
-        if (chance < 50) {
+        if (chance < 50 && statuses.size() < 100) {
             final TaskStatus status = generateTaskStatus();
             statuses.add(status);
             listeners.forEach(l -> l.taskAdded(status));
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java
index 47ea13859..64ca79739 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/AbstractGridContainerMenu.java
@@ -207,15 +207,14 @@ public void setViewType(final GridViewType viewType) {
     }
 
     public void setSearchBox(final GridSearchBox searchBox) {
-        registerViewUpdatingListener(searchBox);
-        configureSearchBox(searchBox);
-    }
-
-    private void registerViewUpdatingListener(final GridSearchBox theSearchBox) {
-        theSearchBox.addListener(text -> {
+        searchBox.addListener(text -> {
             final boolean valid = onSearchTextChanged(text);
-            theSearchBox.setValid(valid);
+            searchBox.setValid(valid);
         });
+        if (Platform.INSTANCE.getConfig().getGrid().isRememberSearchQuery()) {
+            searchBox.setValue(lastSearchQuery);
+            searchBox.addListener(AbstractGridContainerMenu::updateLastSearchQuery);
+        }
     }
 
     private boolean onSearchTextChanged(final String text) {
@@ -228,13 +227,6 @@ private boolean onSearchTextChanged(final String text) {
         }
     }
 
-    private void configureSearchBox(final GridSearchBox theSearchBox) {
-        if (Platform.INSTANCE.getConfig().getGrid().isRememberSearchQuery()) {
-            theSearchBox.setValue(lastSearchQuery);
-            theSearchBox.addListener(AbstractGridContainerMenu::updateLastSearchQuery);
-        }
-    }
-
     private static void updateLastSearchQuery(final String text) {
         lastSearchQuery = text;
     }
diff --git a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java
index 072ba8151..d7b34c58f 100644
--- a/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java
+++ b/refinedstorage-network-api/src/main/java/com/refinedmods/refinedstorage/api/network/autocrafting/AutocraftingNetworkComponent.java
@@ -2,6 +2,7 @@
 
 import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
 import com.refinedmods.refinedstorage.api.autocrafting.preview.PreviewProvider;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
 import com.refinedmods.refinedstorage.api.network.NetworkComponent;
 import com.refinedmods.refinedstorage.api.resource.ResourceKey;
 
@@ -10,7 +11,7 @@
 import org.apiguardian.api.API;
 
 @API(status = API.Status.STABLE, since = "2.0.0-milestone.4.8")
-public interface AutocraftingNetworkComponent extends NetworkComponent, PreviewProvider {
+public interface AutocraftingNetworkComponent extends NetworkComponent, PreviewProvider, TaskStatusProvider {
     void addListener(PatternListener listener);
 
     void removeListener(PatternListener listener);
diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/FakeTaskStatusProvider.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/FakeTaskStatusProvider.java
new file mode 100644
index 000000000..9a180e45e
--- /dev/null
+++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/FakeTaskStatusProvider.java
@@ -0,0 +1,40 @@
+package com.refinedmods.refinedstorage.network.test.fixtures;
+
+import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
+
+import java.util.List;
+
+public class FakeTaskStatusProvider implements TaskStatusProvider {
+    @Override
+    public List<TaskStatus> getStatuses() {
+        return List.of();
+    }
+
+    @Override
+    public void addListener(final TaskStatusListener listener) {
+        // no op
+    }
+
+    @Override
+    public void removeListener(final TaskStatusListener listener) {
+        // no op
+    }
+
+    @Override
+    public void cancel(final TaskId taskId) {
+        // no op
+    }
+
+    @Override
+    public void cancelAll() {
+        // no op
+    }
+
+    @Override
+    public void testUpdate() {
+        // no op
+    }
+}
diff --git a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/NetworkTestFixtures.java b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/NetworkTestFixtures.java
index 7be2b7176..86c0261f5 100644
--- a/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/NetworkTestFixtures.java
+++ b/refinedstorage-network-test/src/main/java/com/refinedmods/refinedstorage/network/test/fixtures/NetworkTestFixtures.java
@@ -39,7 +39,7 @@ public final class NetworkTestFixtures {
         );
         NETWORK_COMPONENT_MAP_FACTORY.addFactory(
             AutocraftingNetworkComponent.class,
-            network -> new AutocraftingNetworkComponentImpl()
+            network -> new AutocraftingNetworkComponentImpl(new FakeTaskStatusProvider())
         );
     }
 
diff --git a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java
index e3407c8f3..ed4e2741c 100644
--- a/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java
+++ b/refinedstorage-network/src/main/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImpl.java
@@ -2,9 +2,13 @@
 
 import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
 import com.refinedmods.refinedstorage.api.autocrafting.PatternRepositoryImpl;
+import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
 import com.refinedmods.refinedstorage.api.autocrafting.preview.Preview;
 import com.refinedmods.refinedstorage.api.autocrafting.preview.PreviewItem;
 import com.refinedmods.refinedstorage.api.autocrafting.preview.PreviewType;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusProvider;
 import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent;
 import com.refinedmods.refinedstorage.api.network.autocrafting.ParentContainer;
 import com.refinedmods.refinedstorage.api.network.autocrafting.PatternListener;
@@ -22,6 +26,11 @@ public class AutocraftingNetworkComponentImpl implements AutocraftingNetworkComp
     private final Set<PatternProvider> providers = new HashSet<>();
     private final Set<PatternListener> listeners = new HashSet<>();
     private final PatternRepositoryImpl patternRepository = new PatternRepositoryImpl();
+    private final TaskStatusProvider taskStatusProvider;
+
+    public AutocraftingNetworkComponentImpl(final TaskStatusProvider taskStatusProvider) {
+        this.taskStatusProvider = taskStatusProvider;
+    }
 
     @Override
     public void onContainerAdded(final NetworkNodeContainer container) {
@@ -88,13 +97,43 @@ public void addListener(final PatternListener listener) {
         listeners.add(listener);
     }
 
+    @Override
+    public void addListener(final TaskStatusListener listener) {
+        taskStatusProvider.addListener(listener);
+    }
+
     @Override
     public void removeListener(final PatternListener listener) {
         listeners.remove(listener);
     }
 
+    @Override
+    public void removeListener(final TaskStatusListener listener) {
+        taskStatusProvider.removeListener(listener);
+    }
+
     @Override
     public Set<Pattern> getPatterns() {
         return patternRepository.getAll();
     }
+
+    @Override
+    public List<TaskStatus> getStatuses() {
+        return taskStatusProvider.getStatuses();
+    }
+
+    @Override
+    public void cancel(final TaskId taskId) {
+        taskStatusProvider.cancel(taskId);
+    }
+
+    @Override
+    public void cancelAll() {
+        taskStatusProvider.cancelAll();
+    }
+
+    @Override
+    public void testUpdate() {
+        taskStatusProvider.testUpdate();
+    }
 }
diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
index cebdb63ee..4200f04d6 100644
--- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
+++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
@@ -2,6 +2,7 @@
 
 import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode;
 import com.refinedmods.refinedstorage.api.network.node.container.NetworkNodeContainer;
+import com.refinedmods.refinedstorage.network.test.fixtures.FakeTaskStatusProvider;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -14,7 +15,7 @@ class AutocraftingNetworkComponentImplTest {
 
     @BeforeEach
     void setUp() {
-        sut = new AutocraftingNetworkComponentImpl();
+        sut = new AutocraftingNetworkComponentImpl(new FakeTaskStatusProvider());
     }
 
     @Test

From 4bb264dcdeb57aec9854b437e9578291b806617b Mon Sep 17 00:00:00 2001
From: raoulvdberge <raoulvdberge@gmail.com>
Date: Sun, 17 Nov 2024 11:35:37 +0100
Subject: [PATCH 2/2] feat: wireless autocrafting monitor

---
 CHANGELOG.md                                  |   2 +
 config/checkstyle/checkstyle-suppressions.xml |   1 +
 .../common/AbstractClientModInitializer.java  |   9 ++
 .../common/AbstractModInitializer.java        |   8 ++
 .../refinedstorage/common/Config.java         |  12 +++
 .../monitor/AutocraftingMonitor.java          |   2 +
 .../AutocraftingMonitorBlockEntity.java       |   7 +-
 .../monitor/WirelessAutocraftingMonitor.java  |  81 ++++++++++++++++++
 ...elessAutocraftingMonitorContainerMenu.java |  19 ++++
 ...tocraftingMonitorExtendedMenuProvider.java |  47 ++++++++++
 .../WirelessAutocraftingMonitorItem.java      |  65 ++++++++++++++
 .../common/content/ContentIds.java            |   6 ++
 .../common/content/ContentNames.java          |  12 +++
 .../common/content/CreativeModeTabItems.java  |   3 +
 .../common/content/DefaultEnergyUsage.java    |   5 ++
 .../refinedstorage/common/content/Items.java  |  21 +++++
 .../common/content/KeyMappings.java           |  11 +++
 .../refinedstorage/common/content/Menus.java  |  13 +++
 .../common/grid/WirelessGridItem.java         |   8 +-
 .../assets/refinedstorage/lang/en_us.json     |  17 +++-
 ...reative_wireless_autocrafting_monitor.json |  17 ++++
 .../item/wireless_autocrafting_monitor.json   |  17 ++++
 .../wireless_autocrafting_monitor/active.json |   6 ++
 .../inactive.json                             |   6 ++
 .../wireless_autocrafting_monitor/active.png  | Bin 0 -> 548 bytes
 .../inactive.png                              | Bin 0 -> 522 bytes
 .../advancement/wireless_monitoring.json      |  28 ++++++
 .../recipe/wireless_autocrafting_monitor.json |  25 ++++++
 .../fabric/ClientModInitializerImpl.java      |  16 ++++
 .../refinedstorage/fabric/ConfigImpl.java     |  39 +++++++++
 .../fabric/ModInitializerImpl.java            |  32 +++++++
 .../neoforge/ClientModInitializer.java        |  19 ++++
 .../refinedstorage/neoforge/ConfigImpl.java   |  65 ++++++++++++++
 .../neoforge/ModInitializer.java              |  32 +++++++
 .../AutocraftingNetworkComponentImplTest.java |  46 ++++++++++
 35 files changed, 692 insertions(+), 5 deletions(-)
 create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitor.java
 create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorContainerMenu.java
 create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorExtendedMenuProvider.java
 create mode 100644 refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorItem.java
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/creative_wireless_autocrafting_monitor.json
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor.json
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/active.json
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/inactive.json
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/active.png
 create mode 100644 refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/inactive.png
 create mode 100644 refinedstorage-common/src/main/resources/data/refinedstorage/advancement/wireless_monitoring.json
 create mode 100644 refinedstorage-common/src/main/resources/data/refinedstorage/recipe/wireless_autocrafting_monitor.json

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01c39d647..6ac22324d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 ### Added
 
 -   Autocrafting Monitor
+-   Wireless Autocrafting Monitor
+-   Creative Wireless Autocrafting Monitor
 
 ### Changed
 
diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml
index 8b6e49245..3e6eb5b83 100644
--- a/config/checkstyle/checkstyle-suppressions.xml
+++ b/config/checkstyle/checkstyle-suppressions.xml
@@ -7,6 +7,7 @@
     <suppress checks="JavadocPackage" files="test[\\/].*.java"/>
     <!-- Mod initializer can be longer due to initialization logic, config can be long too -->
     <suppress checks="FileLength" files="(ModInitializer.*\.java|ConfigImpl\.java)"/>
+    <suppress checks="MethodCount" files="Items.java"/>
     <!-- Shadow target contains underscore -->
     <suppress checks="MemberName" files="ModelBakerImplMixin.java"/>
     <suppress checks="HideUtilityClassConstructor" files="GridClearPacket.java"/>
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java
index 7e4c75034..bbc1b946b 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractClientModInitializer.java
@@ -108,6 +108,7 @@ public AutocraftingPreviewScreen create(final AutocraftingPreviewContainerMenu m
             });
         registration.register(Menus.INSTANCE.getAutocrafterManager(), AutocrafterManagerScreen::new);
         registration.register(Menus.INSTANCE.getAutocraftingMonitor(), AutocraftingMonitorScreen::new);
+        registration.register(Menus.INSTANCE.getWirelessAutocraftingMonitor(), AutocraftingMonitorScreen::new);
     }
 
     protected static void registerAlternativeGridHints() {
@@ -142,6 +143,14 @@ protected static void handleInputEvents() {
                 Items.INSTANCE.getCreativePortableGrid()
             );
         }
+        final KeyMapping openWirelessAutocraftingMonitor = KeyMappings.INSTANCE.getOpenWirelessAutocraftingMonitor();
+        while (openWirelessAutocraftingMonitor != null && openWirelessAutocraftingMonitor.consumeClick()) {
+            RefinedStorageApi.INSTANCE.useSlotReferencedItem(
+                player,
+                Items.INSTANCE.getWirelessAutocraftingMonitor(),
+                Items.INSTANCE.getCreativeWirelessAutocraftingMonitor()
+            );
+        }
     }
 
     protected static void registerDiskModels() {
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
index 5f7f8d8ee..4e2233a1a 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/AbstractModInitializer.java
@@ -29,6 +29,7 @@
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorData;
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.TaskStatusProviderImpl;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.WirelessAutocraftingMonitorContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridBlockEntity;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridData;
@@ -826,6 +827,13 @@ protected final void registerMenus(final RegistryCallback<MenuType<?>> callback,
                 AutocraftingMonitorData.STREAM_CODEC
             )
         ));
+        Menus.INSTANCE.setWirelessAutocraftingMonitor(callback.register(
+            ContentIds.WIRELESS_AUTOCRAFTING_MONITOR,
+            () -> extendedMenuTypeFactory.create(
+                WirelessAutocraftingMonitorContainerMenu::new,
+                AutocraftingMonitorData.STREAM_CODEC
+            )
+        ));
     }
 
     protected final void registerLootFunctions(final RegistryCallback<LootItemFunctionType<?>> callback) {
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java
index 9482cbb74..1fd5fb666 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/Config.java
@@ -85,6 +85,8 @@ public interface Config {
 
     SimpleEnergyUsageEntry getAutocraftingMonitor();
 
+    WirelessAutocraftingMonitorEntry getWirelessAutocraftingMonitor();
+
     interface SimpleEnergyUsageEntry {
         long getEnergyUsage();
     }
@@ -228,4 +230,14 @@ interface AutocrafterManagerEntry extends SimpleEnergyUsageEntry {
 
         AutocrafterManagerViewType getViewType();
     }
+
+    interface WirelessAutocraftingMonitorEntry {
+        long getEnergyCapacity();
+
+        long getOpenEnergyUsage();
+
+        long getCancelEnergyUsage();
+
+        long getCancelAllEnergyUsage();
+    }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
index 3bb5b3259..a3198c9f2 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitor.java
@@ -6,4 +6,6 @@ interface AutocraftingMonitor extends TaskStatusProvider {
     void addWatcher(AutocraftingMonitorWatcher watcher);
 
     void removeWatcher(AutocraftingMonitorWatcher watcher);
+
+    boolean isAutocraftingMonitorActive();
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
index ddd57f10d..402e57252 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/AutocraftingMonitorBlockEntity.java
@@ -57,7 +57,7 @@ protected boolean doesBlockStateChangeWarrantNetworkNodeUpdate(final BlockState
 
     @Override
     public AutocraftingMonitorData getMenuData() {
-        return new AutocraftingMonitorData(getStatuses(), mainNetworkNode.isActive());
+        return new AutocraftingMonitorData(getStatuses(), isAutocraftingMonitorActive());
     }
 
     @Override
@@ -117,4 +117,9 @@ public void addWatcher(final AutocraftingMonitorWatcher watcher) {
     public void removeWatcher(final AutocraftingMonitorWatcher watcher) {
         watchers.remove(watcher);
     }
+
+    @Override
+    public boolean isAutocraftingMonitorActive() {
+        return mainNetworkNode.isActive();
+    }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitor.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitor.java
new file mode 100644
index 000000000..7fea8c646
--- /dev/null
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitor.java
@@ -0,0 +1,81 @@
+package com.refinedmods.refinedstorage.common.autocrafting.monitor;
+
+import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
+import com.refinedmods.refinedstorage.api.network.autocrafting.AutocraftingNetworkComponent;
+import com.refinedmods.refinedstorage.api.network.energy.EnergyNetworkComponent;
+import com.refinedmods.refinedstorage.common.Platform;
+import com.refinedmods.refinedstorage.common.api.support.network.item.NetworkItemContext;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+class WirelessAutocraftingMonitor implements AutocraftingMonitor {
+    private final NetworkItemContext context;
+
+    WirelessAutocraftingMonitor(final NetworkItemContext context) {
+        this.context = context;
+    }
+
+    private Optional<AutocraftingNetworkComponent> getAutocrafting() {
+        return context.resolveNetwork().map(network -> network.getComponent(AutocraftingNetworkComponent.class));
+    }
+
+    @Override
+    public void addWatcher(final AutocraftingMonitorWatcher watcher) {
+        context.drainEnergy(Platform.INSTANCE.getConfig().getWirelessAutocraftingMonitor().getOpenEnergyUsage());
+    }
+
+    @Override
+    public void removeWatcher(final AutocraftingMonitorWatcher watcher) {
+        // no op
+    }
+
+    @Override
+    public boolean isAutocraftingMonitorActive() {
+        final boolean networkActive = context.resolveNetwork().map(
+            network -> network.getComponent(EnergyNetworkComponent.class).getStored() > 0
+        ).orElse(false);
+        return networkActive && context.isActive();
+    }
+
+    @Override
+    public List<TaskStatus> getStatuses() {
+        return getAutocrafting().map(AutocraftingNetworkComponent::getStatuses).orElse(Collections.emptyList());
+    }
+
+    @Override
+    public void addListener(final TaskStatusListener listener) {
+        getAutocrafting().ifPresent(autocrafting -> autocrafting.addListener(listener));
+    }
+
+    @Override
+    public void removeListener(final TaskStatusListener listener) {
+        getAutocrafting().ifPresent(autocrafting -> autocrafting.removeListener(listener));
+    }
+
+    @Override
+    public void cancel(final TaskId taskId) {
+        getAutocrafting().ifPresent(autocrafting -> {
+            autocrafting.cancel(taskId);
+            context.drainEnergy(Platform.INSTANCE.getConfig().getWirelessAutocraftingMonitor().getCancelEnergyUsage());
+        });
+    }
+
+    @Override
+    public void cancelAll() {
+        getAutocrafting().ifPresent(autocrafting -> {
+            autocrafting.cancelAll();
+            context.drainEnergy(
+                Platform.INSTANCE.getConfig().getWirelessAutocraftingMonitor().getCancelAllEnergyUsage()
+            );
+        });
+    }
+
+    @Override
+    public void testUpdate() {
+        getAutocrafting().ifPresent(AutocraftingNetworkComponent::testUpdate);
+    }
+}
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorContainerMenu.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorContainerMenu.java
new file mode 100644
index 000000000..ba5fd82ad
--- /dev/null
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorContainerMenu.java
@@ -0,0 +1,19 @@
+package com.refinedmods.refinedstorage.common.autocrafting.monitor;
+
+import com.refinedmods.refinedstorage.common.content.Menus;
+
+import net.minecraft.world.entity.player.Inventory;
+
+public class WirelessAutocraftingMonitorContainerMenu extends AbstractAutocraftingMonitorContainerMenu {
+    public WirelessAutocraftingMonitorContainerMenu(final int syncId,
+                                                    final Inventory playerInventory,
+                                                    final AutocraftingMonitorData data) {
+        super(Menus.INSTANCE.getWirelessAutocraftingMonitor(), syncId, playerInventory, data);
+    }
+
+    WirelessAutocraftingMonitorContainerMenu(final int syncId,
+                                             final Inventory playerInventory,
+                                             final AutocraftingMonitor autocraftingMonitor) {
+        super(Menus.INSTANCE.getWirelessAutocraftingMonitor(), syncId, playerInventory.player, autocraftingMonitor);
+    }
+}
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorExtendedMenuProvider.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorExtendedMenuProvider.java
new file mode 100644
index 000000000..d2a643fee
--- /dev/null
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorExtendedMenuProvider.java
@@ -0,0 +1,47 @@
+package com.refinedmods.refinedstorage.common.autocrafting.monitor;
+
+import com.refinedmods.refinedstorage.common.support.containermenu.ExtendedMenuProvider;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.codec.StreamEncoder;
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+
+class WirelessAutocraftingMonitorExtendedMenuProvider implements ExtendedMenuProvider<AutocraftingMonitorData> {
+    private final Component name;
+    private final AutocraftingMonitor autocraftingMonitor;
+
+    WirelessAutocraftingMonitorExtendedMenuProvider(final Component name,
+                                                    final AutocraftingMonitor autocraftingMonitor) {
+        this.name = name;
+        this.autocraftingMonitor = autocraftingMonitor;
+    }
+
+    @Override
+    public AutocraftingMonitorData getMenuData() {
+        return new AutocraftingMonitorData(
+            autocraftingMonitor.getStatuses(),
+            autocraftingMonitor.isAutocraftingMonitorActive()
+        );
+    }
+
+    @Override
+    public StreamEncoder<RegistryFriendlyByteBuf, AutocraftingMonitorData> getMenuCodec() {
+        return AutocraftingMonitorData.STREAM_CODEC;
+    }
+
+    @Override
+    public Component getDisplayName() {
+        return name;
+    }
+
+    @Nullable
+    @Override
+    public AbstractContainerMenu createMenu(final int syncId, final Inventory inventory, final Player player) {
+        return new WirelessAutocraftingMonitorContainerMenu(syncId, inventory, autocraftingMonitor);
+    }
+}
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorItem.java
new file mode 100644
index 000000000..6426f704a
--- /dev/null
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/autocrafting/monitor/WirelessAutocraftingMonitorItem.java
@@ -0,0 +1,65 @@
+package com.refinedmods.refinedstorage.common.autocrafting.monitor;
+
+import com.refinedmods.refinedstorage.api.network.energy.EnergyStorage;
+import com.refinedmods.refinedstorage.api.network.impl.energy.EnergyStorageImpl;
+import com.refinedmods.refinedstorage.common.Platform;
+import com.refinedmods.refinedstorage.common.api.RefinedStorageApi;
+import com.refinedmods.refinedstorage.common.api.security.SecurityHelper;
+import com.refinedmods.refinedstorage.common.api.support.energy.AbstractNetworkEnergyItem;
+import com.refinedmods.refinedstorage.common.api.support.network.item.NetworkItemContext;
+import com.refinedmods.refinedstorage.common.api.support.slotreference.SlotReference;
+import com.refinedmods.refinedstorage.common.content.ContentNames;
+import com.refinedmods.refinedstorage.common.security.BuiltinPermission;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+
+import static java.util.Objects.requireNonNullElse;
+
+public class WirelessAutocraftingMonitorItem extends AbstractNetworkEnergyItem {
+    private final boolean creative;
+
+    public WirelessAutocraftingMonitorItem(final boolean creative) {
+        super(
+            new Item.Properties().stacksTo(1),
+            RefinedStorageApi.INSTANCE.getEnergyItemHelper(),
+            RefinedStorageApi.INSTANCE.getNetworkItemHelper()
+        );
+        this.creative = creative;
+    }
+
+    public EnergyStorage createEnergyStorage(final ItemStack stack) {
+        final EnergyStorage energyStorage = new EnergyStorageImpl(
+            Platform.INSTANCE.getConfig().getWirelessAutocraftingMonitor().getEnergyCapacity()
+        );
+        return RefinedStorageApi.INSTANCE.asItemEnergyStorage(energyStorage, stack);
+    }
+
+    @Override
+    protected void use(@Nullable final Component name,
+                       final ServerPlayer player,
+                       final SlotReference slotReference,
+                       final NetworkItemContext context) {
+        final boolean isAllowed = context.resolveNetwork()
+            .map(network -> SecurityHelper.isAllowed(player, BuiltinPermission.OPEN, network))
+            .orElse(true);
+        if (!isAllowed) {
+            RefinedStorageApi.INSTANCE.sendNoPermissionToOpenMessage(
+                player,
+                ContentNames.WIRELESS_AUTOCRAFTING_MONITOR
+            );
+            return;
+        }
+        final WirelessAutocraftingMonitor autocraftingMonitor = new WirelessAutocraftingMonitor(context);
+        final Component correctedName = requireNonNullElse(
+            name,
+            creative ? ContentNames.CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR : ContentNames.WIRELESS_AUTOCRAFTING_MONITOR
+        );
+        final var provider = new WirelessAutocraftingMonitorExtendedMenuProvider(correctedName, autocraftingMonitor);
+        Platform.INSTANCE.getMenuOpener().openMenu(player, provider);
+    }
+}
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentIds.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentIds.java
index 1b3ae4fce..1c3d9cec2 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentIds.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentIds.java
@@ -70,6 +70,12 @@ public final class ContentIds {
     public static final ResourceLocation AUTOCRAFTER = createIdentifier("autocrafter");
     public static final ResourceLocation AUTOCRAFTER_MANAGER = createIdentifier("autocrafter_manager");
     public static final ResourceLocation AUTOCRAFTING_MONITOR = createIdentifier("autocrafting_monitor");
+    public static final ResourceLocation WIRELESS_AUTOCRAFTING_MONITOR = createIdentifier(
+        "wireless_autocrafting_monitor"
+    );
+    public static final ResourceLocation CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR = createIdentifier(
+        "creative_wireless_autocrafting_monitor"
+    );
 
     private ContentIds() {
     }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentNames.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentNames.java
index dcccc402c..dc026ac38 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentNames.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/ContentNames.java
@@ -42,6 +42,14 @@ public final class ContentNames {
     public static final MutableComponent AUTOCRAFTER = name("autocrafter");
     public static final MutableComponent AUTOCRAFTER_MANAGER = name("autocrafter_manager");
     public static final MutableComponent AUTOCRAFTING_MONITOR = name("autocrafting_monitor");
+    public static final MutableComponent WIRELESS_AUTOCRAFTING_MONITOR = createTranslation(
+        "item",
+        "wireless_autocrafting_monitor"
+    );
+    public static final MutableComponent CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR = createTranslation(
+        "item",
+        "creative_wireless_autocrafting_monitor"
+    );
 
     public static final String CLEAR_CRAFTING_MATRIX_TO_NETWORK_TRANSLATION_KEY =
         createTranslationKey("key", "clear_crafting_grid_matrix_to_network");
@@ -50,6 +58,10 @@ public final class ContentNames {
     public static final String FOCUS_SEARCH_BAR_TRANSLATION_KEY = createTranslationKey("key", "focus_search_bar");
     public static final String OPEN_WIRELESS_GRID_TRANSLATION_KEY = createTranslationKey("key", "open_wireless_grid");
     public static final String OPEN_PORTABLE_GRID_TRANSLATION_KEY = createTranslationKey("key", "open_portable_grid");
+    public static final String OPEN_WIRELESS_AUTOCRAFTING_MONITOR_TRANSLATION_KEY = createTranslationKey(
+        "key",
+        "open_wireless_autocrafting_monitor"
+    );
 
     private ContentNames() {
     }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/CreativeModeTabItems.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/CreativeModeTabItems.java
index c368aeba3..ae1f7c489 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/CreativeModeTabItems.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/CreativeModeTabItems.java
@@ -115,5 +115,8 @@ private static void appendItems(final Consumer<ItemStack> consumer) {
         itemConsumer.accept(Items.INSTANCE.getSecurityCard());
         itemConsumer.accept(Items.INSTANCE.getFallbackSecurityCard());
         itemConsumer.accept(Items.INSTANCE.getPattern());
+        itemConsumer.accept(Items.INSTANCE.getWirelessAutocraftingMonitor());
+        consumer.accept(Items.INSTANCE.getWirelessAutocraftingMonitor().createAtEnergyCapacity());
+        itemConsumer.accept(Items.INSTANCE.getCreativeWirelessAutocraftingMonitor());
     }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DefaultEnergyUsage.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DefaultEnergyUsage.java
index 12196696f..fcf0cbe09 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DefaultEnergyUsage.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/DefaultEnergyUsage.java
@@ -67,6 +67,11 @@ public final class DefaultEnergyUsage {
     public static final long PORTABLE_GRID_INSERT = 5;
     public static final long PORTABLE_GRID_EXTRACT = 5;
 
+    public static final long WIRELESS_AUTOCRAFTING_MONITOR_CAPACITY = 1000;
+    public static final long WIRELESS_AUTOCRAFTING_MONITOR_OPEN = 5;
+    public static final long WIRELESS_AUTOCRAFTING_MONITOR_CANCEL = 5;
+    public static final long WIRELESS_AUTOCRAFTING_MONITOR_CANCEL_ALL = 5;
+
     private DefaultEnergyUsage() {
     }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Items.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Items.java
index 9471ab294..99bc66e7a 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Items.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Items.java
@@ -2,6 +2,7 @@
 
 import com.refinedmods.refinedstorage.common.api.upgrade.AbstractUpgradeItem;
 import com.refinedmods.refinedstorage.common.autocrafting.PatternItem;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.WirelessAutocraftingMonitorItem;
 import com.refinedmods.refinedstorage.common.controller.ControllerBlockItem;
 import com.refinedmods.refinedstorage.common.controller.CreativeControllerBlockItem;
 import com.refinedmods.refinedstorage.common.grid.WirelessGridItem;
@@ -109,6 +110,10 @@ public final class Items {
     private Supplier<FallbackSecurityCardItem> fallbackSecurityCard;
     @Nullable
     private Supplier<PatternItem> pattern;
+    @Nullable
+    private Supplier<WirelessAutocraftingMonitorItem> wirelessAutocraftingMonitor;
+    @Nullable
+    private Supplier<WirelessAutocraftingMonitorItem> creativeWirelessAutocraftingMonitor;
 
     private Items() {
     }
@@ -512,4 +517,20 @@ public PatternItem getPattern() {
     public void setPattern(final Supplier<PatternItem> supplier) {
         this.pattern = supplier;
     }
+
+    public WirelessAutocraftingMonitorItem getWirelessAutocraftingMonitor() {
+        return requireNonNull(wirelessAutocraftingMonitor).get();
+    }
+
+    public void setWirelessAutocraftingMonitor(final Supplier<WirelessAutocraftingMonitorItem> supplier) {
+        this.wirelessAutocraftingMonitor = supplier;
+    }
+
+    public WirelessAutocraftingMonitorItem getCreativeWirelessAutocraftingMonitor() {
+        return requireNonNull(creativeWirelessAutocraftingMonitor).get();
+    }
+
+    public void setCreativeWirelessAutocraftingMonitor(final Supplier<WirelessAutocraftingMonitorItem> supplier) {
+        this.creativeWirelessAutocraftingMonitor = supplier;
+    }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/KeyMappings.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/KeyMappings.java
index ee88ed6ae..b6f3568f1 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/KeyMappings.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/KeyMappings.java
@@ -18,6 +18,8 @@ public final class KeyMappings {
     private KeyMapping openWirelessGrid;
     @Nullable
     private KeyMapping openPortableGrid;
+    @Nullable
+    private KeyMapping openWirelessAutocraftingMonitor;
 
     private KeyMappings() {
     }
@@ -65,4 +67,13 @@ public KeyMapping getOpenPortableGrid() {
     public void setOpenPortableGrid(final KeyMapping openPortableGrid) {
         this.openPortableGrid = openPortableGrid;
     }
+
+    @Nullable
+    public KeyMapping getOpenWirelessAutocraftingMonitor() {
+        return openWirelessAutocraftingMonitor;
+    }
+
+    public void setOpenWirelessAutocraftingMonitor(final KeyMapping openWirelessAutocraftingMonitor) {
+        this.openWirelessAutocraftingMonitor = openWirelessAutocraftingMonitor;
+    }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java
index 408b8b124..6984f5744 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/content/Menus.java
@@ -3,6 +3,7 @@
 import com.refinedmods.refinedstorage.common.autocrafting.autocrafter.AutocrafterContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.autocraftermanager.AutocrafterManagerContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.monitor.AutocraftingMonitorContainerMenu;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.WirelessAutocraftingMonitorContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.patterngrid.PatternGridContainerMenu;
 import com.refinedmods.refinedstorage.common.autocrafting.preview.AutocraftingPreviewContainerMenu;
 import com.refinedmods.refinedstorage.common.constructordestructor.ConstructorContainerMenu;
@@ -101,6 +102,8 @@ public final class Menus {
     private Supplier<MenuType<AutocrafterManagerContainerMenu>> autocrafterManager;
     @Nullable
     private Supplier<MenuType<AutocraftingMonitorContainerMenu>> autocraftingMonitor;
+    @Nullable
+    private Supplier<MenuType<WirelessAutocraftingMonitorContainerMenu>> wirelessAutocraftingMonitor;
 
     private Menus() {
     }
@@ -348,4 +351,14 @@ public MenuType<AutocraftingMonitorContainerMenu> getAutocraftingMonitor() {
     public void setAutocraftingMonitor(final Supplier<MenuType<AutocraftingMonitorContainerMenu>> autocraftingMonitor) {
         this.autocraftingMonitor = autocraftingMonitor;
     }
+
+    public MenuType<WirelessAutocraftingMonitorContainerMenu> getWirelessAutocraftingMonitor() {
+        return requireNonNull(wirelessAutocraftingMonitor).get();
+    }
+
+    public void setWirelessAutocraftingMonitor(
+        final Supplier<MenuType<WirelessAutocraftingMonitorContainerMenu>> wirelessAutocraftingMonitor
+    ) {
+        this.wirelessAutocraftingMonitor = wirelessAutocraftingMonitor;
+    }
 }
diff --git a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGridItem.java b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGridItem.java
index f620203d2..3a3c3d7b4 100644
--- a/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGridItem.java
+++ b/refinedstorage-common/src/main/java/com/refinedmods/refinedstorage/common/grid/WirelessGridItem.java
@@ -47,14 +47,16 @@ protected void use(@Nullable final Component name,
                        final NetworkItemContext context) {
         final boolean isAllowed = context.resolveNetwork()
             .map(network -> SecurityHelper.isAllowed(player, BuiltinPermission.OPEN, network))
-            .orElse(true); // if the network can't be resolved that will be apparent later in the UI.
+            .orElse(true);
         if (!isAllowed) {
             RefinedStorageApi.INSTANCE.sendNoPermissionToOpenMessage(player, ContentNames.WIRELESS_GRID);
             return;
         }
         final Grid grid = new WirelessGrid(context);
-        final Component correctedName = requireNonNullElse(name,
-            creative ? ContentNames.CREATIVE_WIRELESS_GRID : ContentNames.WIRELESS_GRID);
+        final Component correctedName = requireNonNullElse(
+            name,
+            creative ? ContentNames.CREATIVE_WIRELESS_GRID : ContentNames.WIRELESS_GRID
+        );
         final var provider = new WirelessGridExtendedMenuProvider(correctedName, grid, slotReference);
         Platform.INSTANCE.getMenuOpener().openMenu(player, provider);
     }
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json
index ac8896191..da5e49fda 100644
--- a/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json
+++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/lang/en_us.json
@@ -365,6 +365,8 @@
   "item.refinedstorage.pattern.help": "Used in autocrafting to store the recipe to be crafted. Use while crouching to clear.",
   "item.refinedstorage.autocrafter_manager.help": "Allows managing all your autocrafters from a single interface.",
   "item.refinedstorage.autocrafting_monitor.help": "Displays the status of autocrafting tasks and allows you to cancel autocrafting tasks in your storage network.",
+  "item.refinedstorage.wireless_autocrafting_monitor": "Wireless Autocrafting Monitor",
+  "item.refinedstorage.creative_wireless_autocrafting_monitor": "Creative Wireless Autocrafting Monitor",
   "misc.refinedstorage.stored": "Stored: %s",
   "misc.refinedstorage.stored_with_capacity": "Stored: %s / %s (%d%%)",
   "misc.refinedstorage.total": "%d total",
@@ -401,6 +403,7 @@
   "key.refinedstorage.clear_crafting_grid_matrix_to_inventory": "Clear Crafting Grid matrix to inventory",
   "key.refinedstorage.open_wireless_grid": "Open Wireless Grid",
   "key.refinedstorage.open_portable_grid": "Open Portable Grid",
+  "key.refinedstorage.open_wireless_autocrafting_monitor": "Open Wireless Autocrafting Monitor",
   "refinedstorage.subtitle.wrench": "Wrench used",
   "permission.refinedstorage.insert": "Insert",
   "permission.refinedstorage.insert.description": "Whether the player can insert resources in a network.",
@@ -649,6 +652,16 @@
   "text.autoconfig.refinedstorage.option.autocraftingMonitor.tooltip": "Configuration for the Autocrafting Monitor.",
   "text.autoconfig.refinedstorage.option.autocraftingMonitor.energyUsage": "Energy usage",
   "text.autoconfig.refinedstorage.option.autocraftingMonitor.energyUsage.tooltip": "The energy used by the Autocrafting Monitor.",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor": "Wireless Autocrafting Monitor",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.tooltip": "Configuration for the Wireless Autocrafting Monitor.",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.energyCapacity": "Energy capacity",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.energyCapacity.tooltip": "The energy capacity of the Wireless Autocrafting Monitor.",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.openEnergyUsage": "Open energy usage",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.openEnergyUsage.tooltip": "The energy used by the Wireless Autocrafting Monitor to open.",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.cancelEnergyUsage": "Cancel energy usage",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.cancelEnergyUsage.tooltip": "The energy used by the Wireless Autocrafting Monitor to cancel a task.",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.cancelAllEnergyUsage": "Cancel all energy usage",
+  "text.autoconfig.refinedstorage.option.wirelessAutocraftingMonitor.cancelAllEnergyUsage.tooltip": "The energy used by the Wireless Autocrafting Monitor to cancel all tasks.",
   "advancements.refinedstorage.root.description": "Use one or multiple Controllers in a storage network to provide your network with energy",
   "advancements.refinedstorage.connecting": "Connecting",
   "advancements.refinedstorage.connecting.description": "Use Cable to connect devices with each other, or place devices against each other",
@@ -697,5 +710,7 @@
   "advancements.refinedstorage.managing_patterns": "Managing patterns",
   "advancements.refinedstorage.managing_patterns.description": "Craft an Autocrafter Manager to manage your patterns in a centralized interface",
   "advancements.refinedstorage.monitoring": "Monitoring",
-  "advancements.refinedstorage.monitoring.description": "Check the status of your autocrafting tasks with a Autocrafting Monitor"
+  "advancements.refinedstorage.monitoring.description": "Check the status of your autocrafting tasks with a Autocrafting Monitor",
+  "advancements.refinedstorage.wireless_monitoring": "Wireless monitoring",
+  "advancements.refinedstorage.wireless_monitoring.description": "Check the status of your autocrafting tasks wirelessly with a Wireless Autocrafting Monitor"
 }
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/creative_wireless_autocrafting_monitor.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/creative_wireless_autocrafting_monitor.json
new file mode 100644
index 000000000..4adcac16b
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/creative_wireless_autocrafting_monitor.json
@@ -0,0 +1,17 @@
+{
+  "parent": "item/generated",
+  "overrides": [
+    {
+      "predicate": {
+        "refinedstorage:network_bound_active": 0
+      },
+      "model": "refinedstorage:item/wireless_autocrafting_monitor/inactive"
+    },
+    {
+      "predicate": {
+        "refinedstorage:network_bound_active": 1
+      },
+      "model": "refinedstorage:item/wireless_autocrafting_monitor/active"
+    }
+  ]
+}
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor.json
new file mode 100644
index 000000000..4adcac16b
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor.json
@@ -0,0 +1,17 @@
+{
+  "parent": "item/generated",
+  "overrides": [
+    {
+      "predicate": {
+        "refinedstorage:network_bound_active": 0
+      },
+      "model": "refinedstorage:item/wireless_autocrafting_monitor/inactive"
+    },
+    {
+      "predicate": {
+        "refinedstorage:network_bound_active": 1
+      },
+      "model": "refinedstorage:item/wireless_autocrafting_monitor/active"
+    }
+  ]
+}
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/active.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/active.json
new file mode 100644
index 000000000..c89d3952c
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "item/generated",
+  "textures": {
+    "layer0": "refinedstorage:item/wireless_autocrafting_monitor/active"
+  }
+}
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/inactive.json b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/inactive.json
new file mode 100644
index 000000000..5352e0add
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/assets/refinedstorage/models/item/wireless_autocrafting_monitor/inactive.json
@@ -0,0 +1,6 @@
+{
+  "parent": "item/generated",
+  "textures": {
+    "layer0": "refinedstorage:item/wireless_autocrafting_monitor/inactive"
+  }
+}
diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/active.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/active.png
new file mode 100644
index 0000000000000000000000000000000000000000..704b6e8ac9f61d024771ca05bc59db28df70cede
GIT binary patch
literal 548
zcmV+<0^9wGP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006O%
z3;baP00009a7bBm000ib000ib0l1NC?EnA(8FWQhbW?9;ba!ELWdLwtX>N2bZe?^J
zG%heMF)~90YwQ330ij7mK~y+TrIJlc0#O)+>;JTKmq8(c(8r>og@WRs<F_epR8$B8
z2XO?!L0q_U7p3N66h%b@L#SD(zoJcLAw;Xwy?5oL15%5_;U3O?c;7p-1K?lU7;ci;
zY$mpzuLXMA3NV>WcEjN?0)YUiN25_B5(z{i5tapmL6DB-j^+>wg;1~8(Q36Y7!1(w
z_nCUV9u!4Exm;$T)jJx1APDGmIxyV5;#~O#_pro8;}a*h3+$cpkR%B{pN~{^0CePL
zvx(#TH^>WUbm$XNEEeH(I!RRrKzD4n+c;}1asB)b=hFu+AHT4#zToIef-K9RQ?B08
z0O-TfUFq1rCpZvpP^nbl@pwp82jFtKP_0(k!%e4CsH%$DY=-f8jBdA!TrLN@-A<}H
z0Q#*R4hP(BH`~=_vw`P%<`#>ExyfWARULrQXoS^jMX6LmHk(BzlR=?SV4lzC!Eqc6
z1_P<;0Q`PGYPA~X^EpPN5r)Gd8=q!$ExMl9>m^kk0987jW`AEQm13SuCJ~FpAc`X5
m@i?hy`<laFv@zUX*!cl1+Sjc;Wdx!C0000<MNUMnLSTYD#pksE

literal 0
HcmV?d00001

diff --git a/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/inactive.png b/refinedstorage-common/src/main/resources/assets/refinedstorage/textures/item/wireless_autocrafting_monitor/inactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6491595ae29fae80fe99bc5879b57c613b2b140
GIT binary patch
literal 522
zcmV+l0`>igP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006O%
z3;baP00009a7bBm000ia000ia0czHX2><{98FWQhbW?9;ba!ELWdLwtX>N2bZe?^J
zG%heMF)~90YwQ330f$LMK~y+TrBY3+K~WU-{)jSBMudq>WTNiSh$8a+aU&CiDG8-W
z21e$T0U{)&Obqacmb3TBd7RRFgVj1`we~uD?|TgZ{)La?C-{6mLGSvTpu$%Hm&@g+
zP$(dm%YnF5Dxq4fqF5}lme1!QJW`Ex(RCg3`5dd&3Wvi1`~9A=+wHJiE-@aDIq0=U
z3P>ap*lad%I2>@h-Ecace74)|uvjeUcDu-AGQz3|pq3Yl1#C7OG)<FWHk&aR3=oUO
zgjEqhGp^Tbe%0ggz~yrB*=n`IWHMnm9D=%ht&sv~aWpFx{O-VLG-5KDAeBl9t0EvC
zk7GKW^5Sl{8?M(Y?)N*+=QFn3EjpbJ!r`#6Dgx+RM<Nj<lS!U66bd04jWP!U0cNk)
zE3AqD+I%n=#Aq}^yWK{!*+jqJXYTcS@caF|lh+z4Ae+r%Hk;w`c;Iw8;dnf9`=rrW
zG+sKL7FI<7q0wmY-&e2KnQOHg%H=XztrjYkim=Fj>GBtR6u$=yPh!Wnnb-~6djJ3c
M07*qoM6N<$f^D<j+W-In

literal 0
HcmV?d00001

diff --git a/refinedstorage-common/src/main/resources/data/refinedstorage/advancement/wireless_monitoring.json b/refinedstorage-common/src/main/resources/data/refinedstorage/advancement/wireless_monitoring.json
new file mode 100644
index 000000000..1333c277b
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/data/refinedstorage/advancement/wireless_monitoring.json
@@ -0,0 +1,28 @@
+{
+  "display": {
+    "icon": {
+      "id": "refinedstorage:wireless_autocrafting_monitor"
+    },
+    "title": {
+      "translate": "advancements.refinedstorage.wireless_monitoring"
+    },
+    "description": {
+      "translate": "advancements.refinedstorage.wireless_monitoring.description"
+    }
+  },
+  "parent": "refinedstorage:wireless",
+  "criteria": {
+    "wireless_autocrafting_monitor_in_inventory": {
+      "trigger": "minecraft:inventory_changed",
+      "conditions": {
+        "items": [
+          {
+            "items": [
+              "refinedstorage:wireless_autocrafting_monitor"
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/refinedstorage-common/src/main/resources/data/refinedstorage/recipe/wireless_autocrafting_monitor.json b/refinedstorage-common/src/main/resources/data/refinedstorage/recipe/wireless_autocrafting_monitor.json
new file mode 100644
index 000000000..4d034ef5d
--- /dev/null
+++ b/refinedstorage-common/src/main/resources/data/refinedstorage/recipe/wireless_autocrafting_monitor.json
@@ -0,0 +1,25 @@
+{
+  "type": "minecraft:crafting_shaped",
+  "pattern": [
+    "EPE",
+    "EME",
+    "EAE"
+  ],
+  "key": {
+    "E": {
+      "item": "refinedstorage:quartz_enriched_iron"
+    },
+    "P": {
+      "tag": "c:ender_pearls"
+    },
+    "M": {
+      "tag": "refinedstorage:autocrafting_monitors"
+    },
+    "A": {
+      "item": "refinedstorage:advanced_processor"
+    }
+  },
+  "result": {
+    "id": "refinedstorage:wireless_autocrafting_monitor"
+  }
+}
\ No newline at end of file
diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java
index 68df1c279..db3ddc104 100644
--- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java
+++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ClientModInitializerImpl.java
@@ -515,6 +515,12 @@ private void registerKeyBindings() {
             InputConstants.UNKNOWN.getValue(),
             ContentNames.MOD_TRANSLATION_KEY
         )));
+        KeyMappings.INSTANCE.setOpenWirelessAutocraftingMonitor(KeyBindingHelper.registerKeyBinding(new KeyMapping(
+            ContentNames.OPEN_WIRELESS_AUTOCRAFTING_MONITOR_TRANSLATION_KEY,
+            InputConstants.Type.KEYSYM,
+            InputConstants.UNKNOWN.getValue(),
+            ContentNames.MOD_TRANSLATION_KEY
+        )));
         ClientTickEvents.END_CLIENT_TICK.register(client -> handleInputEvents());
     }
 
@@ -552,6 +558,16 @@ private void registerItemProperties() {
             SecurityCardItemPropertyFunction.NAME,
             new SecurityCardItemPropertyFunction()
         );
+        ItemProperties.register(
+            Items.INSTANCE.getWirelessAutocraftingMonitor(),
+            NetworkItemPropertyFunction.NAME,
+            new NetworkItemPropertyFunction()
+        );
+        ItemProperties.register(
+            Items.INSTANCE.getCreativeWirelessAutocraftingMonitor(),
+            NetworkItemPropertyFunction.NAME,
+            new NetworkItemPropertyFunction()
+        );
     }
 
     private void registerItemColors() {
diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java
index 1f790e368..faf653b88 100644
--- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java
+++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ConfigImpl.java
@@ -134,6 +134,10 @@ public class ConfigImpl implements ConfigData, com.refinedmods.refinedstorage.co
         DefaultEnergyUsage.AUTOCRAFTING_MONITOR
     );
 
+    @ConfigEntry.Gui.CollapsibleObject
+    private WirelessAutocraftingMonitorEntryImpl wirelessAutocraftingMonitor =
+        new WirelessAutocraftingMonitorEntryImpl();
+
     public static ConfigImpl get() {
         return AutoConfig.getConfigHolder(ConfigImpl.class).getConfig();
     }
@@ -320,6 +324,11 @@ public SimpleEnergyUsageEntry getAutocraftingMonitor() {
         return autocraftingMonitor;
     }
 
+    @Override
+    public WirelessAutocraftingMonitorEntry getWirelessAutocraftingMonitor() {
+        return wirelessAutocraftingMonitor;
+    }
+
     private static class GridEntryImpl implements GridEntry {
         private boolean largeFont = false;
 
@@ -798,4 +807,34 @@ private static void save() {
             AutoConfig.getConfigHolder(ConfigImpl.class).save();
         }
     }
+
+    private static class WirelessAutocraftingMonitorEntryImpl implements WirelessAutocraftingMonitorEntry {
+        private long energyCapacity = DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CAPACITY;
+
+        private long openEnergyUsage = DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_OPEN;
+
+        private long cancelEnergyUsage = DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CANCEL;
+
+        private long cancelAllEnergyUsage = DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CANCEL_ALL;
+
+        @Override
+        public long getEnergyCapacity() {
+            return energyCapacity;
+        }
+
+        @Override
+        public long getOpenEnergyUsage() {
+            return openEnergyUsage;
+        }
+
+        @Override
+        public long getCancelEnergyUsage() {
+            return cancelEnergyUsage;
+        }
+
+        @Override
+        public long getCancelAllEnergyUsage() {
+            return cancelAllEnergyUsage;
+        }
+    }
 }
diff --git a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java
index 35763ef00..90339f198 100644
--- a/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java
+++ b/refinedstorage-fabric/src/main/java/com/refinedmods/refinedstorage/fabric/ModInitializerImpl.java
@@ -4,6 +4,7 @@
 import com.refinedmods.refinedstorage.common.PlatformProxy;
 import com.refinedmods.refinedstorage.common.api.RefinedStorageApi;
 import com.refinedmods.refinedstorage.common.api.support.network.AbstractNetworkNodeContainerBlockEntity;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.WirelessAutocraftingMonitorItem;
 import com.refinedmods.refinedstorage.common.content.BlockEntities;
 import com.refinedmods.refinedstorage.common.content.BlockEntityProvider;
 import com.refinedmods.refinedstorage.common.content.BlockEntityProviders;
@@ -152,11 +153,13 @@
 import team.reborn.energy.api.EnergyStorage;
 
 import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_PORTABLE_GRID;
+import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_WIRELESS_GRID;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.FALLBACK_SECURITY_CARD;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.PORTABLE_GRID;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.REGULATOR_UPGRADE;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.SECURITY_CARD;
+import static com.refinedmods.refinedstorage.common.content.ContentIds.WIRELESS_AUTOCRAFTING_MONITOR;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.WIRELESS_GRID;
 import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier;
 import static com.refinedmods.refinedstorage.fabric.support.resource.VariantUtil.toFluidVariant;
@@ -402,6 +405,30 @@ public boolean allowComponentsUpdateAnimation(final Player player,
                 }
             }
         ));
+        Items.INSTANCE.setWirelessAutocraftingMonitor(callback.register(
+            WIRELESS_AUTOCRAFTING_MONITOR,
+            () -> new WirelessAutocraftingMonitorItem(false) {
+                @Override
+                public boolean allowComponentsUpdateAnimation(final Player player,
+                                                              final InteractionHand hand,
+                                                              final ItemStack oldStack,
+                                                              final ItemStack newStack) {
+                    return AbstractModInitializer.allowComponentsUpdateAnimation(oldStack, newStack);
+                }
+            }
+        ));
+        Items.INSTANCE.setCreativeWirelessAutocraftingMonitor(callback.register(
+            CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR,
+            () -> new WirelessAutocraftingMonitorItem(true) {
+                @Override
+                public boolean allowComponentsUpdateAnimation(final Player player,
+                                                              final InteractionHand hand,
+                                                              final ItemStack oldStack,
+                                                              final ItemStack newStack) {
+                    return AbstractModInitializer.allowComponentsUpdateAnimation(oldStack, newStack);
+                }
+            }
+        ));
     }
 
     private void registerCreativeModeTab() {
@@ -812,6 +839,11 @@ private void registerEnergyItemProviders() {
             (stack, context) -> new EnergyStorageAdapter(PortableGridBlockItem.createEnergyStorage(stack)),
             Items.INSTANCE.getPortableGrid()
         );
+        EnergyStorage.ITEM.registerForItems(
+            (stack, context) ->
+                new EnergyStorageAdapter(Items.INSTANCE.getWirelessAutocraftingMonitor().createEnergyStorage(stack)),
+            Items.INSTANCE.getWirelessAutocraftingMonitor()
+        );
     }
 
     private void registerTickHandler() {
diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java
index 786ca5497..81a3a4e24 100644
--- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java
+++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ClientModInitializer.java
@@ -167,6 +167,15 @@ public static void onRegisterKeyMappings(final RegisterKeyMappingsEvent e) {
         );
         e.register(openPortableGrid);
         KeyMappings.INSTANCE.setOpenPortableGrid(openPortableGrid);
+
+        final KeyMapping openWirelessAutocraftingMonitor = new KeyMapping(
+            ContentNames.OPEN_WIRELESS_AUTOCRAFTING_MONITOR_TRANSLATION_KEY,
+            KeyConflictContext.IN_GAME,
+            InputConstants.UNKNOWN,
+            ContentNames.MOD_TRANSLATION_KEY
+        );
+        e.register(openWirelessAutocraftingMonitor);
+        KeyMappings.INSTANCE.setOpenWirelessAutocraftingMonitor(openWirelessAutocraftingMonitor);
     }
 
     private static void registerBlockEntityRenderer() {
@@ -260,5 +269,15 @@ private static void registerItemProperties() {
             SecurityCardItemPropertyFunction.NAME,
             new SecurityCardItemPropertyFunction()
         );
+        ItemProperties.register(
+            Items.INSTANCE.getWirelessAutocraftingMonitor(),
+            NetworkItemPropertyFunction.NAME,
+            new NetworkItemPropertyFunction()
+        );
+        ItemProperties.register(
+            Items.INSTANCE.getCreativeWirelessAutocraftingMonitor(),
+            NetworkItemPropertyFunction.NAME,
+            new NetworkItemPropertyFunction()
+        );
     }
 }
diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java
index d3e6dd7c2..b6ffbb6ea 100644
--- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java
+++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ConfigImpl.java
@@ -58,6 +58,7 @@ public class ConfigImpl implements Config {
     private final AutocrafterEntryImpl autocrafter;
     private final AutocrafterManagerEntryImpl autocrafterManager;
     private final SimpleEnergyUsageEntry autocraftingMonitor;
+    private final WirelessAutocraftingMonitorEntryImpl wirelessAutocraftingMonitor;
 
     public ConfigImpl() {
         screenSize = builder
@@ -111,6 +112,7 @@ public ConfigImpl() {
             "autocraftingMonitor",
             DefaultEnergyUsage.AUTOCRAFTING_MONITOR
         );
+        wirelessAutocraftingMonitor = new WirelessAutocraftingMonitorEntryImpl();
         spec = builder.build();
     }
 
@@ -304,6 +306,11 @@ public SimpleEnergyUsageEntry getAutocraftingMonitor() {
         return autocraftingMonitor;
     }
 
+    @Override
+    public WirelessAutocraftingMonitorEntry getWirelessAutocraftingMonitor() {
+        return wirelessAutocraftingMonitor;
+    }
+
     private static String translationKey(final String value) {
         return createTranslationKey("text.autoconfig", "option." + value);
     }
@@ -838,18 +845,22 @@ private class WirelessGridEntryImpl implements WirelessGridEntry {
             builder.pop();
         }
 
+        @Override
         public long getEnergyCapacity() {
             return energyCapacity.get();
         }
 
+        @Override
         public long getOpenEnergyUsage() {
             return openEnergyUsage.get();
         }
 
+        @Override
         public long getExtractEnergyUsage() {
             return extractEnergyUsage.get();
         }
 
+        @Override
         public long getInsertEnergyUsage() {
             return insertEnergyUsage.get();
         }
@@ -870,10 +881,12 @@ private class WirelessTransmitterEntryImpl implements WirelessTransmitterEntry {
             builder.pop();
         }
 
+        @Override
         public long getEnergyUsage() {
             return energyUsage.get();
         }
 
+        @Override
         public int getBaseRange() {
             return baseRange.get();
         }
@@ -902,18 +915,22 @@ private class PortableGridEntryImpl implements PortableGridEntry {
             builder.pop();
         }
 
+        @Override
         public long getEnergyCapacity() {
             return energyCapacity.get();
         }
 
+        @Override
         public long getOpenEnergyUsage() {
             return openEnergyUsage.get();
         }
 
+        @Override
         public long getExtractEnergyUsage() {
             return extractEnergyUsage.get();
         }
 
+        @Override
         public long getInsertEnergyUsage() {
             return insertEnergyUsage.get();
         }
@@ -1021,4 +1038,52 @@ public long getEnergyUsage() {
             return energyUsage.get();
         }
     }
+
+    private class WirelessAutocraftingMonitorEntryImpl implements WirelessAutocraftingMonitorEntry {
+        private final ModConfigSpec.LongValue energyCapacity;
+        private final ModConfigSpec.LongValue openEnergyUsage;
+        private final ModConfigSpec.LongValue cancelEnergyUsage;
+        private final ModConfigSpec.LongValue cancelAllEnergyUsage;
+
+        WirelessAutocraftingMonitorEntryImpl() {
+            builder.translation(translationKey("wirelessAutocraftingMonitor")).push("wirelessAutocraftingMonitor");
+            energyCapacity = builder
+                .translation(translationKey("wirelessAutocraftingMonitor." + ENERGY_CAPACITY))
+                .defineInRange(ENERGY_CAPACITY, DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CAPACITY, 0,
+                    Long.MAX_VALUE);
+            openEnergyUsage = builder
+                .translation(translationKey("wirelessAutocraftingMonitor.openEnergyUsage"))
+                .defineInRange("openEnergyUsage", DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_OPEN, 0,
+                    Long.MAX_VALUE);
+            cancelEnergyUsage = builder
+                .translation(translationKey("wirelessAutocraftingMonitor.cancelEnergyUsage"))
+                .defineInRange("cancelEnergyUsage", DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CANCEL, 0,
+                    Long.MAX_VALUE);
+            cancelAllEnergyUsage = builder
+                .translation(translationKey("wirelessAutocraftingMonitor.cancelAllEnergyUsage"))
+                .defineInRange("cancelAllEnergyUsage", DefaultEnergyUsage.WIRELESS_AUTOCRAFTING_MONITOR_CANCEL_ALL, 0,
+                    Long.MAX_VALUE);
+            builder.pop();
+        }
+
+        @Override
+        public long getEnergyCapacity() {
+            return energyCapacity.get();
+        }
+
+        @Override
+        public long getOpenEnergyUsage() {
+            return openEnergyUsage.get();
+        }
+
+        @Override
+        public long getCancelEnergyUsage() {
+            return cancelEnergyUsage.get();
+        }
+
+        @Override
+        public long getCancelAllEnergyUsage() {
+            return cancelAllEnergyUsage.get();
+        }
+    }
 }
diff --git a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java
index 785edbcc4..de22470b2 100644
--- a/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java
+++ b/refinedstorage-neoforge/src/main/java/com/refinedmods/refinedstorage/neoforge/ModInitializer.java
@@ -6,6 +6,7 @@
 import com.refinedmods.refinedstorage.common.api.RefinedStorageApi;
 import com.refinedmods.refinedstorage.common.api.support.network.AbstractNetworkNodeContainerBlockEntity;
 import com.refinedmods.refinedstorage.common.api.support.network.NetworkNodeContainerProvider;
+import com.refinedmods.refinedstorage.common.autocrafting.monitor.WirelessAutocraftingMonitorItem;
 import com.refinedmods.refinedstorage.common.content.BlockEntities;
 import com.refinedmods.refinedstorage.common.content.BlockEntityProvider;
 import com.refinedmods.refinedstorage.common.content.BlockEntityProviders;
@@ -154,11 +155,13 @@
 import net.neoforged.neoforge.registries.RegisterEvent;
 
 import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_PORTABLE_GRID;
+import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.CREATIVE_WIRELESS_GRID;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.FALLBACK_SECURITY_CARD;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.PORTABLE_GRID;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.REGULATOR_UPGRADE;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.SECURITY_CARD;
+import static com.refinedmods.refinedstorage.common.content.ContentIds.WIRELESS_AUTOCRAFTING_MONITOR;
 import static com.refinedmods.refinedstorage.common.content.ContentIds.WIRELESS_GRID;
 import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.MOD_ID;
 import static com.refinedmods.refinedstorage.common.util.IdentifierUtil.createIdentifier;
@@ -366,6 +369,28 @@ public boolean shouldCauseReequipAnimation(final ItemStack oldStack,
                 }
             }
         ));
+        Items.INSTANCE.setWirelessAutocraftingMonitor(callback.register(
+            WIRELESS_AUTOCRAFTING_MONITOR,
+            () -> new WirelessAutocraftingMonitorItem(false) {
+                @Override
+                public boolean shouldCauseReequipAnimation(final ItemStack oldStack,
+                                                           final ItemStack newStack,
+                                                           final boolean slotChanged) {
+                    return AbstractModInitializer.allowComponentsUpdateAnimation(oldStack, newStack);
+                }
+            }
+        ));
+        Items.INSTANCE.setCreativeWirelessAutocraftingMonitor(callback.register(
+            CREATIVE_WIRELESS_AUTOCRAFTING_MONITOR,
+            () -> new WirelessAutocraftingMonitorItem(true) {
+                @Override
+                public boolean shouldCauseReequipAnimation(final ItemStack oldStack,
+                                                           final ItemStack newStack,
+                                                           final boolean slotChanged) {
+                    return AbstractModInitializer.allowComponentsUpdateAnimation(oldStack, newStack);
+                }
+            }
+        ));
     }
 
     private void registerBlockEntities(final IEventBus eventBus) {
@@ -479,6 +504,13 @@ private void registerCapabilities(final RegisterCapabilitiesEvent event) {
             (stack, ctx) -> new EnergyStorageAdapter(PortableGridBlockItem.createEnergyStorage(stack)),
             Items.INSTANCE.getPortableGrid()
         );
+        event.registerItem(
+            Capabilities.EnergyStorage.ITEM,
+            (stack, ctx) -> new EnergyStorageAdapter(
+                Items.INSTANCE.getWirelessAutocraftingMonitor().createEnergyStorage(stack)
+            ),
+            Items.INSTANCE.getWirelessAutocraftingMonitor()
+        );
         event.registerBlockEntity(
             Capabilities.ItemHandler.BLOCK,
             BlockEntities.INSTANCE.getDiskInterface(),
diff --git a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
index 4200f04d6..2683c6deb 100644
--- a/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
+++ b/refinedstorage-network/src/test/java/com/refinedmods/refinedstorage/api/network/impl/autocrafting/AutocraftingNetworkComponentImplTest.java
@@ -1,9 +1,16 @@
 package com.refinedmods.refinedstorage.api.network.impl.autocrafting;
 
+import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
+import com.refinedmods.refinedstorage.api.autocrafting.TaskId;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
+import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusListener;
+import com.refinedmods.refinedstorage.api.network.autocrafting.PatternListener;
 import com.refinedmods.refinedstorage.api.network.impl.node.patternprovider.PatternProviderNetworkNode;
 import com.refinedmods.refinedstorage.api.network.node.container.NetworkNodeContainer;
 import com.refinedmods.refinedstorage.network.test.fixtures.FakeTaskStatusProvider;
 
+import java.util.UUID;
+
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -18,6 +25,45 @@ void setUp() {
         sut = new AutocraftingNetworkComponentImpl(new FakeTaskStatusProvider());
     }
 
+    @Test
+    void temporaryCoverage() {
+        final PatternListener listener = new PatternListener() {
+            @Override
+            public void onAdded(final Pattern pattern) {
+                // no op
+            }
+
+            @Override
+            public void onRemoved(final Pattern pattern) {
+                // no op
+            }
+        };
+        sut.addListener(listener);
+        sut.removeListener(listener);
+        final TaskStatusListener listener2 = new TaskStatusListener() {
+            @Override
+            public void taskStatusChanged(final TaskStatus status) {
+                // no op
+            }
+
+            @Override
+            public void taskRemoved(final TaskId id) {
+                // no op
+            }
+
+            @Override
+            public void taskAdded(final TaskStatus status) {
+                // no op
+            }
+        };
+        sut.addListener(listener2);
+        sut.removeListener(listener2);
+        sut.getStatuses();
+        sut.cancel(new TaskId(UUID.randomUUID()));
+        sut.cancelAll();
+        sut.testUpdate();
+    }
+
     @Test
     void shouldAddPatternsFromPatternProvider() {
         // Arrange