2025-12-27 15:06:02 +00:00

195 lines
5.5 KiB
JavaScript

import { useContext, useState, useEffect } from 'react'
import { Typography, Spin, Flex, Space, Slider, Descriptions, Tag } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { ApiServerContext } from '../context/ApiServerContext'
import PropTypes from 'prop-types'
import merge from 'lodash/merge'
const { Text } = Typography
const PrinterMiscPanel = ({ id, showControls = true }) => {
const { subscribeToObjectEvent, connected, sendObjectAction } =
useContext(ApiServerContext)
const [miscData, setMiscData] = useState({
fan: {
speed: 0,
target: 0
},
lcdBacklight: {
brightness: 0
},
beeper: {
value: 0
},
filamentSensor: {
enabled: false,
filamentDetected: false
},
coolingFan: {
speed: 0
}
})
const [fanSpeed, setFanSpeed] = useState(0)
const [lcdBrightness, setLcdBrightness] = useState(0)
const [beeperValue, setBeeperValue] = useState(0)
useEffect(() => {
if (id && connected == true) {
const miscEventUnsubscribe = subscribeToObjectEvent(
id,
'printer',
'misc',
(event) => {
setMiscData((prev) => {
const merged = merge({}, prev, event.data)
return merged
})
}
)
return () => {
if (miscEventUnsubscribe) miscEventUnsubscribe()
}
}
}, [id, connected, subscribeToObjectEvent])
useEffect(() => {
if (miscData.fan?.speed !== undefined) {
setFanSpeed(miscData.fan.speed)
}
if (miscData.lcdBacklight?.brightness !== undefined) {
setLcdBrightness(miscData.lcdBacklight.brightness)
}
if (miscData.beeper?.value !== undefined) {
setBeeperValue(miscData.beeper.value)
}
}, [
miscData.fan?.speed,
miscData.lcdBacklight?.brightness,
miscData.beeper?.value
])
const handleSetFanSpeed = (value) => {
if (id && connected == true) {
sendObjectAction(id, 'printer', {
type: 'gcodeScript',
data: {
script: `M106 S${Math.round(value * 255)}`
}
})
}
}
const handleSetLcdBrightness = (value) => {
if (id && connected == true) {
sendObjectAction(id, 'printer', {
type: 'gcodeScript',
data: {
script: `SET_LCD LCD=lcd_backlight BRIGHTNESS=${value}`
}
})
}
}
const handleSetBeeperValue = (value) => {
if (id && connected == true) {
sendObjectAction(id, 'printer', {
type: 'gcodeScript',
data: {
script: `M300 S440 P200 V${Math.round(value * 100)}`
}
})
}
}
return (
<div style={{ minWidth: 190 }}>
{miscData ? (
<Flex vertical gap='middle'>
<Flex vertical gap={'middle'}>
{showControls && (
<>
<Space direction='vertical' style={{ width: '100%' }}>
<Text>Fan Speed: {Math.round(fanSpeed * 100)}%</Text>
<Slider
value={fanSpeed}
min={0}
max={1}
step={0.01}
onChange={setFanSpeed}
onAfterChange={handleSetFanSpeed}
tooltip={{ open: false }}
/>
<Text>LCD Backlight: {Math.round(lcdBrightness * 100)}%</Text>
<Slider
value={lcdBrightness}
min={0}
max={1}
step={0.01}
onChange={setLcdBrightness}
onAfterChange={handleSetLcdBrightness}
tooltip={{ open: false }}
/>
<Text>Beeper Pitch: {Math.round(beeperValue * 100)}%</Text>
<Slider
value={beeperValue}
min={0}
max={1}
step={0.01}
onChange={setBeeperValue}
onAfterChange={handleSetBeeperValue}
tooltip={{ open: false }}
/>
</Space>
</>
)}
<Descriptions column={1} size='small' bordered>
<Descriptions.Item label='Filament Sensor'>
{miscData.filamentSensor.enabled ? (
miscData.filamentSensor.filamentDetected ? (
<Tag color='green'>Detected</Tag>
) : (
<Tag color='red'>Open</Tag>
)
) : (
<Tag color='default'>Disabled</Tag>
)}
</Descriptions.Item>
<Descriptions.Item label='Part Cooling Fan'>
{miscData.fan.speed > 0 ? (
<Text>Running ({Math.round(miscData.fan.speed * 100)}%)</Text>
) : (
<Text>Off</Text>
)}
</Descriptions.Item>
<Descriptions.Item label='Nozzle Cooling Fan'>
{miscData.coolingFan.speed > 0 ? (
<Text>
Running ({Math.round(miscData.coolingFan.speed * 100)}%)
</Text>
) : (
<Text>Off</Text>
)}
</Descriptions.Item>
</Descriptions>
</Flex>
</Flex>
) : (
<Flex justify='centre'>
<Spin indicator={<LoadingOutlined spin />} size='large' />
</Flex>
)}
</div>
)
}
PrinterMiscPanel.propTypes = {
id: PropTypes.string.isRequired,
showControls: PropTypes.bool
}
export default PrinterMiscPanel