Приборная панель (приложение Engee)
Автор
using Engee, GenieFramework, Sockets
const CTS_SIGNAL = UInt8(0x01)
@app begin
@out output_data_circular = 0.0
@out debug_string_circular = "⚪ Запуск"
@out circular_gauge_string = "rotate(0, 21.55, 21.55)"
@out output_data_linear = 0.0
@out debug_string_linear = "⚪ Запуск"
@out linear_gauge_height = 0.142
@private sender_socket_circular = UDPSocket()
@private sender_socket_linear = UDPSocket()
@onchange isready begin
@async begin
try
udpsock_circular = UDPSocket()
bind(udpsock_circular, ip"127.0.0.1", 5150)
sender_socket_circular = UDPSocket()
udpsock_linear = UDPSocket()
bind(udpsock_linear, ip"127.0.0.1", 5152)
sender_socket_linear = UDPSocket()
while true
# Круглый индикатор
debug_string_circular = "⚪"
send(sender_socket_circular, ip"127.0.0.1", 5151, [CTS_SIGNAL])
data = recv(udpsock_circular);
if length(data) == 8 # Проверка размера данных Float64
output_data_circular = ntoh(reinterpret(Float64, data)[1])
output_data_circular = min(315.5, max(0.0, output_data_circular / 100 * 315.5));
circular_gauge_string = "rotate($output_data_circular, 21.55, 21.55)"
debug_string_circular = "🟢"
else
@warn "Получен некорректный пакет размером $(length(data)) байт"
debug_string_circular = "🟡"
end
# Линейный индикатор
debug_string_linear = "⚪"
send(sender_socket_linear, ip"127.0.0.1", 5153, [CTS_SIGNAL]) # Порт отправителя
data = recv(udpsock_linear);
if length(data) == 8 # Проверка размера данных Float64
output_data_linear = ntoh(reinterpret(Float64, data)[1])
output_data_linear = min(1.0, max(0.0, output_data_linear / 100.0));
zero_height = 31.907
one_height = 0.17376
linear_gauge_height = zero_height - (zero_height-one_height) * output_data_linear
debug_string_linear = "🟢"
else
@warn "Получен некорректный пакет размером $(length(data)) байт"
debug_string_linear = "🟡"
end
# Короткая пауза чтобы не нагружать CPU
sleep(0.1)
end
catch e
@error "Ошибка при работе с UDP-сокетом" exception=e
debug_string_circular = "🔴";
debug_string_linear = "🔴";
finally
close(udpsock_circular)
debug_string_circular = "🟤";
debug_string_linear = "🟤";
end
end
end
end
function ui()
[
row([
column([
p("Состояние: {{debug_string_circular}}"),
svg([
defs([linearGradient([stop(style="stop-color:#e7e7e7", offset="0"), stop(style="stop-color:#c6c6c6;stop-opacity:0", offset="1")], id="linearGradient4839", x1="11.291", x2="42.086", y1="12.927", y2="38.504", gradientTransform="translate(-3.7704 -4.9784)", gradientUnits="userSpaceOnUse"),
linearGradient([stop(style="stop-color:#d9d9d9", offset="0"), stop(style="stop-color:#cacaca;stop-opacity:0", offset="1")], id="linearGradient4911", x1="24.954", x2="25.003", y1="29.95", y2="23.192", gradientTransform="translate(-3.7704 -4.9784)", gradientUnits="userSpaceOnUse")]),
circle(cx="21.55", cy="21.55", r="21.3", style="fill:#fff;stop-color:#000000;stroke-width:.3;stroke:#ccc"),
circle(cx="21.55", cy="21.55", r="20.787", style="fill:url(#linearGradient4839);stop-color:#000000"),
circle(cx="21.55", cy="21.55", r="18.754", style="fill:#d5d5d5;stop-color:#000000;stroke-width:.1;stroke:#b4b4b4"),
circle(cx="21.55", cy="21.55", r="17.405", style="fill:#f2f2f2;stop-color:#000000"),
path(d="m21.614 5.5443v-1.3006", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m34.257 31.214 1.031.79273", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m27.614 36.269.4893 1.205", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m37.491 22.996 1.2948.12255", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m35.954 14.514 1.1694-.5691", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m30.083 7.9784.69059-1.1021", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m13.241 7.9192-.68282-1.1069", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m7.4033 14.253-1.1589-.59036", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m4.4389 23.087 1.295-.12019", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m8.8571 31.064-1.0403.78053", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
path(d="m15.574 36.253-.49255 1.2037", style="fill:none;stop-color:#000000;stroke-width:.41231;stroke:#000"),
text([tspan("50", x="19.967312", y="9.1463127", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="19.967312", y="9.1463127", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("40", x="13.337849", y="11.627018", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="13.337849", y="11.627018", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("30", x="8.504755", y="16.673965", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="8.504755", y="16.673965", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("20", x="6.9650078", y="23.388971", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="6.9650078", y="23.388971", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("10", x="9.4457102", y="30.061201", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="9.4457102", y="30.061201", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("0", x="15.690239", y="34.851524", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="15.690239", y="34.851524", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("60", x="26.639545", y="11.498707", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="26.639545", y="11.498707", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("70", x="31.130474", y="16.716736", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="31.130474", y="16.716736", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("80", x="33.269016", y="23.517282", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="33.269016", y="23.517282", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("90", x="30.146748", y="29.847345", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="30.146748", y="29.847345", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
text([tspan("100", x="23.645596", y="34.124424", style="fill-opacity:1;fill:#333333;font-family:sans-serif;font-size:2.8222px;stroke-width:.4;stroke:none")], x="23.645596", y="34.124424", style="fill-opacity:.88385;fill:#333333;font-family:sans-serif;font-size:2.8222px;line-height:1.4;stop-color:#000000;stroke-width:.4;stroke:#000000"),
# Стрелка прибора
path(d="m21.287 24.405-6.1832 13.013 4.5464-13.716z", style="fill:#f00;stop-color:#000000;transition: transform .2s linear", transform! = "circular_gauge_string"),
circle(cx="21.55", cy="21.55", r="3.6783", style="fill:#fff;stop-color:#000000;stroke-width:.2;stroke:#a2a2a2"),
circle(cx="21.55", cy="21.55", r="3.3607", style="fill:url(#linearGradient4911);stop-color:#000000")
], width="65mm", height="65mm", viewBox="0 0 43 43", style="display: block; margin: 20px auto;"),
], width="66%", align="center", style="min-width:200px"),
column([
p("Состояние: {{debug_string_linear}}"),
svg([
defs([
linearGradient([
stop(style="stop-color:#898989;stop-opacity:0", offset="0"),
stop(style="stop-color:#fff;stop-opacity:.23127", offset=".11472"),
stop(style="stop-color:#fff;stop-opacity:.57003", offset=".30303"),
stop(style="stop-color:#fff;stop-opacity:.47557", offset=".48052"),
stop(style="stop-color:#d4d4d4;stop-opacity:0", offset="1")
], id="linearGradient1538", x1="3.6591", x2="6.4009", y1="17.55", y2="17.55", gradientUnits="userSpaceOnUse"),
radialGradient([
stop(style="stop-color:#fff;stop-opacity:.49511", offset=".42208"),
stop(style="stop-color:#fff;stop-opacity:0", offset=".87013")
], id="radialGradient3924", cx="4.876", cy="1.259", r="1.321", gradientTransform="matrix(.80528 0 0 .77115 .87457 .34898)", gradientUnits="userSpaceOnUse"),
linearGradient([
stop(style="stop-color:#929292;stop-opacity:0", offset=".59524"),
stop(style="stop-color:#525252", offset="1")
], id="linearGradient3959", x1="3.7091", x2="6.3509", y1="17.55", y2="17.55", gradientUnits="userSpaceOnUse"),
radialGradient([
stop(style="stop-color:#fff;stop-opacity:0", offset="0"),
stop(style="stop-color:#282828;stop-opacity:0", offset="1")
], id="radialGradient3924-2", cx="5.0279", cy="1.5769", r="1.321", gradientTransform="translate(.0013088 31.956)", gradientUnits="userSpaceOnUse"),
linearGradient([
stop(style="stop-color:#929292;stop-opacity:0", offset=".8"),
stop(style="stop-color:#525252", offset="1")
], id="linearGradient412", x1="4.9695", x2="4.9695", y1="29.224", y2="34.865", gradientUnits="userSpaceOnUse")
]),
text([tspan("100", x="-0.024027601", y="2.1394436", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="-0.024027601", y="2.1394436", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("0", x="1.5804811", y="33.629482", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="1.5804811", y="33.629482", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("10", x="0.77822286", y="30.480478", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="30.480478", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("20", x="0.77822286", y="27.331474", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="27.331474", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("30", x="0.77822286", y="24.182468", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="24.182468", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("40", x="0.77822286", y="21.033463", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="21.033463", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("50", x="0.77822286", y="17.88446", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="17.88446", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("60", x="0.77822286", y="14.73546", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="14.73546", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("70", x="0.77822286", y="11.586457", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="11.586457", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("80", x="0.77822286", y="8.4374523", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="8.4374523", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
text([tspan("90", x="0.77822286", y="5.2884483", style="fill-opacity:1;fill:#4d4d4d;font-family:sans-serif;font-size:1.4025px;stroke-width:.39757;stroke:none")], transform="scale(.99208 1.008)", x="0.77822286", y="5.2884483", style="fill-opacity:.88385;fill:#4d4d4d;font-family:montserrat;font-size:1.4025px;line-height:1.4;stop-color:#000000;stroke-width:.39757;stroke:#000000"),
rect(x="3.7091", y=".24909", width="2.6418", height="34.602", ry="1.3421", style="fill:#c8c8c8;stop-color:#000000"),
path(d="m3.7093 1.5492v31.96c0 .74351.589 1.342 1.3208 1.342.73177 0 1.3208-.59845 1.3208-1.342v-31.96z", style="fill:#f00;stop-color:#000000"),
# Индикатор уровня
rect(x="3.709", y="1.4783", width="2.642", height! = "linear_gauge_height", ry="0", style="fill:#c8c8c8;stop-color:#000000;transition: height .2s linear"),
rect(x="3.7091", y=".24909", width="2.6418", height="34.602", ry="1.3421", style="fill:url(#linearGradient1538);stop-color:#000000"),
path(d="m3.4731 33.366h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 1.6423h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 4.8146h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 7.987h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 11.159h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 14.332h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 17.504h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 20.677h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 23.849h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 27.021h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
path(d="m3.4731 30.194h-.72318", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#666"),
circle(cx="5.0279", cy="1.5769", r="1.321", style="fill:url(#radialGradient3924);stop-color:#000000"),
circle(cx="5.0292", cy="33.533", r="1.321", style="fill:url(#radialGradient3924-2);stop-color:#000000"),
rect(x="3.7091", y=".24909", width="2.6418", height="34.602", ry="1.3421", style="fill:url(#linearGradient3959);stop-color:#000000"),
rect(x="3.7091", y=".24909", width="2.6418", height="34.602", ry="1.3421", style="fill:url(#linearGradient412);stop-color:#000000"),
rect(x="3.7091", y=".24909", width="2.6418", height="34.602", ry="1.3421", style="fill:none;stop-color:#000000;stroke-width:.3;stroke:#ccc")
], width="25mm", height="65mm", viewBox="0 0 6.3 35", style="display: block; margin: 20px auto;"),
], width="34%", align="center", style="min-width:200px")],
width="100%")
]
end
@page("/", ui)