mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
update darkness reward
This commit is contained in:
@@ -16,6 +16,7 @@ const assignmentService = require('./assignmentService');
|
||||
const {
|
||||
getState: getHomeAssistantState,
|
||||
setEntityState: setHomeAssistantEntityState,
|
||||
setLightsLockedOn: setHomeAssistantLightsLockedOn,
|
||||
} = require('./homeAssistantService');
|
||||
const { getRequestIp, isLocalNetwork, normalizeIp } = require('../helpers/ipResolver');
|
||||
|
||||
@@ -175,7 +176,10 @@ function buildRewardContext() {
|
||||
const entities = getHomeAssistantState()?.entities;
|
||||
return Array.isArray(entities) ? entities : [];
|
||||
},
|
||||
getHomeAssistantLightPolicy: () => getHomeAssistantState()?.lightPolicy || null,
|
||||
setHomeAssistantEntityState,
|
||||
setHomeAssistantLightsLockedOn: (next, options = {}) =>
|
||||
setHomeAssistantLightsLockedOn(next, options),
|
||||
saveEffect: (effectId, payload = {}) => saveEffect(effectId, payload, { broadcast: false }),
|
||||
clearEffect: (effectId) => clearEffect(effectId, { broadcast: false }),
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ const io = require('../globals/io');
|
||||
const roverManager = require('./roverManager');
|
||||
const { isAdmin, isLockdownAdmin } = require('./roleService');
|
||||
const logger = require('../globals/logger').child('commandService');
|
||||
const { isNightVisionBlocked } = require('../rewards/definitions/darkness');
|
||||
|
||||
const pendingCommands = new Map(); // id -> { roverId }
|
||||
const lastDriveActivity = new Map(); // roverId -> { ts, socketId, direction, speed, isAdmin }
|
||||
@@ -70,6 +71,11 @@ io.on('connection', (socket) => {
|
||||
if (type === 'audioLevels') {
|
||||
throw new Error('audioLevels command is service-managed');
|
||||
}
|
||||
if (type === 'nightVision' && isNightVisionBlocked()) {
|
||||
logger.info('Ignoring night vision command while darkness lock is active', { socketId: socket.id, roverId });
|
||||
reply({ ignored: true, reason: 'darknessActive' });
|
||||
return;
|
||||
}
|
||||
const payload = data ? { ...data } : {};
|
||||
const isRebootCommand = type === 'reboot';
|
||||
const isSongCommand = type === 'song' || (type === 'raw' && isSongRawPayload(payload));
|
||||
|
||||
@@ -29,7 +29,7 @@ let connection = null;
|
||||
let unsubscribeEntities = null;
|
||||
let reconnectTimer = null;
|
||||
let connected = false;
|
||||
let lightsLockedOn = false;
|
||||
let lightsLockState = null; // null | 'on' | 'off'
|
||||
let lightsIdleOffTimer = null;
|
||||
let lightsIdleOffDeadline = null;
|
||||
|
||||
@@ -215,7 +215,7 @@ function clearLightsIdleOffTimer() {
|
||||
function scheduleLightsIdleOffTimer() {
|
||||
if (!enabled) return;
|
||||
if (getControllableEntityIds().length === 0) return;
|
||||
if (lightsIdleOffTimer || lightsLockedOn || hasActiveDrivers()) {
|
||||
if (lightsIdleOffTimer || lightsLockState != null || hasActiveDrivers()) {
|
||||
return;
|
||||
}
|
||||
lightsIdleOffDeadline = Date.now() + LIGHT_IDLE_OFF_MS;
|
||||
@@ -238,7 +238,7 @@ function scheduleLightsIdleOffTimer() {
|
||||
}
|
||||
|
||||
function evaluateLightAutomation() {
|
||||
if (lightsLockedOn) {
|
||||
if (lightsLockState != null) {
|
||||
clearLightsIdleOffTimer();
|
||||
return;
|
||||
}
|
||||
@@ -464,12 +464,14 @@ async function setLightColor(entityId, rgbColor) {
|
||||
}
|
||||
|
||||
function isLightControlLocked() {
|
||||
return lightsLockedOn;
|
||||
return lightsLockState != null;
|
||||
}
|
||||
|
||||
function getLightPolicyState() {
|
||||
return {
|
||||
lockedOn: lightsLockedOn,
|
||||
locked: lightsLockState != null,
|
||||
lockState: lightsLockState,
|
||||
lockedOn: lightsLockState === 'on',
|
||||
idleOffMs: LIGHT_IDLE_OFF_MS,
|
||||
idleOffAt: lightsIdleOffDeadline,
|
||||
activeDrivers: getActiveDriverCount(),
|
||||
@@ -478,14 +480,16 @@ function getLightPolicyState() {
|
||||
|
||||
async function setLightsLockedOn(nextValue, options = {}) {
|
||||
const next = Boolean(nextValue);
|
||||
const targetState = options?.targetState === 'off' ? 'off' : 'on';
|
||||
const forceApply = Boolean(options.forceApply);
|
||||
const changed = lightsLockedOn !== next;
|
||||
lightsLockedOn = next;
|
||||
if (lightsLockedOn) {
|
||||
const nextLockState = next ? targetState : null;
|
||||
const changed = lightsLockState !== nextLockState;
|
||||
lightsLockState = nextLockState;
|
||||
if (lightsLockState != null) {
|
||||
clearLightsIdleOffTimer();
|
||||
if (changed || forceApply) {
|
||||
if (enabled) {
|
||||
await setAllControllableEntitiesState('on');
|
||||
await setAllControllableEntitiesState(lightsLockState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -493,16 +497,17 @@ async function setLightsLockedOn(nextValue, options = {}) {
|
||||
}
|
||||
if (changed) {
|
||||
logger.info('Room lights lock state changed', {
|
||||
lockedOn: lightsLockedOn,
|
||||
locked: lightsLockState != null,
|
||||
lockState: lightsLockState,
|
||||
source: options.source || 'unknown',
|
||||
});
|
||||
}
|
||||
emitUpdate();
|
||||
return lightsLockedOn;
|
||||
return lightsLockState === 'on';
|
||||
}
|
||||
|
||||
async function toggleLightsLockedOn(options = {}) {
|
||||
return setLightsLockedOn(!lightsLockedOn, options);
|
||||
return setLightsLockedOn(lightsLockState == null, options);
|
||||
}
|
||||
|
||||
function getState() {
|
||||
@@ -532,7 +537,7 @@ turnEvents.on('queue', () => {
|
||||
|
||||
modeEvents.on('change', (mode) => {
|
||||
if (mode === MODES.ADMIN || mode === MODES.LOCKDOWN) {
|
||||
if (lightsLockedOn) {
|
||||
if (isLightControlLocked()) {
|
||||
setLightsLockedOn(false, { source: 'modeGateReset' }).catch((err) => {
|
||||
logger.warn('Failed to disable lights lock on mode change', err.message);
|
||||
});
|
||||
@@ -554,7 +559,7 @@ io.on('connection', (socket) => {
|
||||
return cb({ error: 'Insufficient permissions to control Home Assistant' });
|
||||
}
|
||||
if (isLightControlLocked()) {
|
||||
return cb({ error: 'Room controls are locked on' });
|
||||
return cb({ error: 'Room controls are locked' });
|
||||
}
|
||||
try {
|
||||
if (!entityId) throw new Error('entityId required');
|
||||
@@ -574,7 +579,7 @@ io.on('connection', (socket) => {
|
||||
return cb({ error: 'Insufficient permissions to control Home Assistant' });
|
||||
}
|
||||
if (isLightControlLocked()) {
|
||||
return cb({ error: 'Room controls are locked on' });
|
||||
return cb({ error: 'Room controls are locked' });
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -595,7 +600,7 @@ io.on('connection', (socket) => {
|
||||
return cb({ error: 'Insufficient permissions to control Home Assistant' });
|
||||
}
|
||||
if (isLightControlLocked()) {
|
||||
return cb({ error: 'Room controls are locked on' });
|
||||
return cb({ error: 'Room controls are locked' });
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user