изменение пинга
This commit is contained in:
parent
e51e895d37
commit
4f5ab1a48b
6 changed files with 68 additions and 8 deletions
25
backend/alembic/versions/0013_device_last_ping_at.py
Normal file
25
backend/alembic/versions/0013_device_last_ping_at.py
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
"""device last_ping_at
|
||||||
|
|
||||||
|
Revision ID: 0013
|
||||||
|
Revises: 0012
|
||||||
|
Create Date: 2026-04-10
|
||||||
|
"""
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
revision = "0013"
|
||||||
|
down_revision = "0012"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
op.add_column(
|
||||||
|
"devices",
|
||||||
|
sa.Column("last_ping_at", sa.DateTime(timezone=True), nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
op.drop_column("devices", "last_ping_at")
|
||||||
|
|
@ -78,6 +78,7 @@ class Device(Base, TimestampMixin):
|
||||||
|
|
||||||
# Monitoring
|
# Monitoring
|
||||||
monitor_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
monitor_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||||
|
last_ping_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||||
last_seen: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
last_seen: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||||
last_ping_ms: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
last_ping_ms: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||||
status: Mapped[str] = mapped_column(String(20), nullable=False, default="unknown")
|
status: Mapped[str] = mapped_column(String(20), nullable=False, default="unknown")
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ class DeviceRead(BaseModel):
|
||||||
device_meta: dict[str, Any] = {}
|
device_meta: dict[str, Any] = {}
|
||||||
capabilities: list[str] = []
|
capabilities: list[str] = []
|
||||||
monitor_enabled: bool
|
monitor_enabled: bool
|
||||||
|
last_ping_at: Optional[datetime] = None
|
||||||
last_seen: Optional[datetime] = None
|
last_seen: Optional[datetime] = None
|
||||||
last_ping_ms: Optional[int] = None
|
last_ping_ms: Optional[int] = None
|
||||||
status: str
|
status: str
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ async def _check_device(
|
||||||
return
|
return
|
||||||
|
|
||||||
device.status = new_status
|
device.status = new_status
|
||||||
|
device.last_ping_at = now
|
||||||
if success:
|
if success:
|
||||||
device.last_seen = now
|
device.last_seen = now
|
||||||
device.last_ping_ms = ping_ms
|
device.last_ping_ms = ping_ms
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,10 @@ export interface DeviceItem {
|
||||||
connection_params: Record<string, unknown>
|
connection_params: Record<string, unknown>
|
||||||
capabilities: string[]
|
capabilities: string[]
|
||||||
status: string
|
status: string
|
||||||
|
monitor_enabled: boolean
|
||||||
|
last_ping_at: string | null
|
||||||
last_seen: string | null
|
last_seen: string | null
|
||||||
last_ping_ms: number | null
|
last_ping_ms: number | null
|
||||||
monitor_enabled: boolean
|
|
||||||
is_active: boolean
|
is_active: boolean
|
||||||
notes: string | null
|
notes: string | null
|
||||||
created_at: string
|
created_at: string
|
||||||
|
|
|
||||||
|
|
@ -427,19 +427,50 @@ export function ObjectDetailPage({ defaultMode = 'inventory' }: { defaultMode?:
|
||||||
row._type === 'group' ? null : <DeviceStatusBadge status={(row as DeviceRow).status} />,
|
row._type === 'group' ? null : <DeviceStatusBadge status={(row as DeviceRow).status} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Последний ping',
|
title: 'Мониторинг',
|
||||||
dataIndex: 'last_seen',
|
key: 'monitoring',
|
||||||
key: 'last_seen',
|
|
||||||
onCell: (row: TableRow) => row._type === 'group' ? { colSpan: 0 } : {},
|
onCell: (row: TableRow) => row._type === 'group' ? { colSpan: 0 } : {},
|
||||||
render: (_: unknown, row: TableRow) => {
|
render: (_: unknown, row: TableRow) => {
|
||||||
if (row._type === 'group') return null
|
if (row._type === 'group') return null
|
||||||
const d = row as DeviceRow
|
const d = row as DeviceRow
|
||||||
if (!d.last_seen) return '—'
|
|
||||||
|
// Мониторинг выключен и история отсутствует
|
||||||
|
if (!d.monitor_enabled && !d.last_ping_at) {
|
||||||
|
return <Typography.Text type="secondary">выключен</Typography.Text>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Мониторинг включён, но ни разу не пинговалось
|
||||||
|
if (d.monitor_enabled && !d.last_ping_at) {
|
||||||
|
return <Typography.Text type="secondary">ожидание...</Typography.Text>
|
||||||
|
}
|
||||||
|
|
||||||
|
const pauseIcon = !d.monitor_enabled
|
||||||
|
? <Tooltip title="Мониторинг выключен"><span style={{ color: '#faad14', marginLeft: 4 }}>⏸</span></Tooltip>
|
||||||
|
: null
|
||||||
|
|
||||||
|
// Устройство online — last_ping_at ≈ last_seen
|
||||||
|
if (d.status === 'online') {
|
||||||
return (
|
return (
|
||||||
<Tooltip title={elapsedAgo(d.last_seen)}>
|
<Tooltip title={elapsedAgo(d.last_ping_at!)}>
|
||||||
<span style={{ cursor: 'default' }}>
|
<span style={{ color: '#52c41a', cursor: 'default' }}>
|
||||||
{dayjs(d.last_seen).format('DD.MM.YYYY HH:mm')}
|
{dayjs(d.last_ping_at).format('DD.MM.YYYY HH:mm')}
|
||||||
</span>
|
</span>
|
||||||
|
{pauseIcon}
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Устройство offline или unknown — показываем время попытки, в tooltip — когда был онлайн
|
||||||
|
const lastSeenHint = d.last_seen
|
||||||
|
? `онлайн был: ${dayjs(d.last_seen).format('DD.MM.YYYY HH:mm')}`
|
||||||
|
: 'онлайн не был'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip title={`${elapsedAgo(d.last_ping_at!)} · ${lastSeenHint}`}>
|
||||||
|
<span style={{ color: '#ff4d4f', cursor: 'default' }}>
|
||||||
|
{dayjs(d.last_ping_at).format('DD.MM.YYYY HH:mm')}
|
||||||
|
</span>
|
||||||
|
{pauseIcon}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue