11#include "skymapcomposite.h"
12#include "fitsviewer/fitsview.h"
13#include "fitsviewer/fitsdata.h"
14#include "indi/indilistener.h"
15#include "hips/hipsfinder.h"
16#include "kstarsdata.h"
17#include "ekos/auxiliary/darklibrary.h"
18#include "ekos/guide/guide.h"
19#include "ekos/align/align.h"
23#include "ekos_debug.h"
27#include <QtConcurrent>
44 connect(
nodeManager->media(), &Node::onBinaryReceived,
this, &Media::onBinaryReceived);
47 connect(
this, &Media::newMetadata,
this, &Media::uploadMetadata);
51 m_TemporaryView.clear();
58bool Media::isConnected()
const
60 return std::any_of(m_NodeManagers.begin(), m_NodeManagers.end(), [](
auto &
nodeManager)
62 return nodeManager->media()->isConnected();
69void Media::onConnected()
75 qCInfo(
KSTARS_EKOS) <<
"Connected to Media Websocket server at" << node->url().toDisplayString();
83void Media::onDisconnected()
89 qCInfo(
KSTARS_EKOS) <<
"Disconnected from Message Websocket server at" << node->url().toDisplayString();
91 if (isConnected() ==
false)
97 temporaryFiles.clear();
106void Media::onTextReceived(
const QString &message)
108 qCInfo(
KSTARS_EKOS) <<
"Media Text Websocket Message" << message;
121 if (command == commands[ALIGN_SET_FILE_EXTENSION])
122 extension = payload[
"ext"].toString();
123 else if (command == commands[SET_BLOBS])
124 m_sendBlobs =
msgObj[
"payload"].toBool();
126 else if (command == commands[ASTRO_GET_OBJECTS_IMAGE])
128 int level = payload[
"level"].toInt(5);
129 double zoom = payload[
"zoom"].toInt(20000);
132 QVariantList objectNames = payload[
"names"].toArray().toVariantList();
134 for (
auto &
oneName : objectNames)
137 SkyObject *
oneObject = KStarsData::Instance()->skyComposite()->findByName(name,
false);
148 <<
"--num_times" <<
"1"
149 <<
"--geometry" <<
QString(
"%1x%2").arg(HIPS_TILE_WIDTH).arg(HIPS_TILE_HEIGHT)
151 <<
"--output" << output);
170 {
"resolution",
QString(
"%1x%2").
arg(HIPS_TILE_WIDTH).
arg(HIPS_TILE_HEIGHT)},
184 meta =
meta.leftJustified(METADATA_PACKET, 0);
194 else if (command == commands[ASTRO_GET_SKYPOINT_IMAGE])
196 int level = payload[
"level"].toInt(5);
197 double zoom = payload[
"zoom"].toInt(20000);
198 double ra = payload[
"ra"].toDouble(0);
199 double de = payload[
"de"].toDouble(0);
200 double width = payload[
"width"].toDouble(512);
201 double height = payload[
"height"].toDouble(512);
209 coords.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->
geo()->lat());
212 volatile auto jnowDEString = coords.dec().toDMSString();
227 {
"uuid",
"skypoint_hips"},
228 {
"name",
"skypoint_hips"},
244 meta =
meta.leftJustified(METADATA_PACKET, 0);
257void Media::onBinaryReceived(
const QByteArray &message)
276 sendData(data,
"+D");
284 if (Options::ekosLiveImageTransfer() ==
false || m_sendBlobs ==
false)
289 m_TemporaryView.reset(
new FITSView());
290 m_TemporaryView->loadData(data);
299 if (Options::ekosLiveImageTransfer() ==
false || m_sendBlobs ==
false)
305 connect(previewImage.get(), &FITSView::loaded,
this, [
this, previewImage]()
307 QtConcurrent::run(this, &Media::upload, previewImage);
309 previewImage->loadFile(filename);
317 if (Options::ekosLiveImageTransfer() ==
false || m_sendBlobs ==
false)
339 imageData->getRecordValue(
"XBINNING",
xbin);
340 imageData->getRecordValue(
"YBINNING",
ybin);
341 imageData->getRecordValue(
"EXPTIME", exposure);
342 imageData->getRecordValue(
"GAIN", gain);
343 imageData->getRecordValue(
"PIXSIZE1",
pixel_size);
344 imageData->getRecordValue(
"FOCALLEN", focal_length);
345 imageData->getRecordValue(
"APTDIA", aperture);
354 {
"resolution", resolution},
356 {
"channels", imageData->channels()},
357 {
"mean", imageData->getAverageMean()},
358 {
"median", imageData->getAverageMedian()},
359 {
"stddev", imageData->getAverageStdDev()},
360 {
"min", imageData->getMin()},
361 {
"max", imageData->getMax()},
365 {
"exposure", exposure.toString()},
366 {
"focal_length", focal_length.toString()},
367 {
"aperture", aperture.toString()},
368 {
"gain", gain.toString()},
373 {
"hasWCS", imageData->hasWCS()},
374 {
"hfr", imageData->getHFR()},
382 meta =
meta.leftJustified(METADATA_PACKET, 0);
385 auto fastImage = (!Options::ekosLiveHighBandwidth() || m_UUID[0] ==
"+");
392 view->getDisplayPixmap();
393 scaledImage.save(&buffer,
ext.toLatin1().constData(), HB_IMAGE_QUALITY);
415 const int32_t width = imageData->width();
416 const int32_t height = imageData->height();
420 imageData->getRecordValue(
"XBINNING",
xbin);
421 imageData->getRecordValue(
"YBINNING",
ybin);
422 imageData->getRecordValue(
"EXPTIME", exposure);
423 imageData->getRecordValue(
"GAIN", gain);
424 imageData->getRecordValue(
"PIXSIZE1",
pixel_size);
425 imageData->getRecordValue(
"FOCALLEN", focal_length);
426 imageData->getRecordValue(
"APTDIA", aperture);
433 {
"resolution", resolution},
435 {
"channels", imageData->channels()},
436 {
"mean", imageData->getAverageMean()},
437 {
"median", imageData->getAverageMedian()},
438 {
"stddev", imageData->getAverageStdDev()},
442 {
"exposure", exposure.toString()},
443 {
"focal_length", focal_length.toString()},
444 {
"aperture", aperture.toString()},
445 {
"gain", gain.toString()},
454 meta =
meta.leftJustified(METADATA_PACKET, 0);
460 if (correctionVector.isNull() ==
false)
463 const double currentZoom = view->getCurrentZoom();
467 scaledImage = view->getDisplayPixmap().scaledToWidth(view->zoomedWidth());
486 scaledImage = view->getDisplayPixmap().width() > HB_IMAGE_WIDTH / 2 ?
488 view->getDisplayPixmap();
492 scaledImage.save(&buffer,
ext.toLatin1().constData(), HB_IMAGE_QUALITY);
502 if (Options::ekosLiveImageTransfer() ==
false || m_sendBlobs ==
false || !frame)
505 int32_t width = Options::ekosLiveHighBandwidth() ? HB_VIDEO_WIDTH : HB_VIDEO_WIDTH / 2;
510 QImage videoImage = (frame->width() > width) ? frame->scaledToWidth(width) : *frame;
519 {
"resolution", resolution},
523 meta =
meta.leftJustified(METADATA_PACKET, 0);
542void Media::registerCameras()
550 camera->disconnect(
this);
551 connect(camera, &ISD::Camera::newVideoFrame,
this, &Media::sendVideoFrame);
556 sendView(view, uuid);
562void Media::resetPolarView()
564 this->correctionVector =
QLineF();
565 m_Manager->alignModule()->zoomAlignView();
568void Media::uploadMetadata(
const QByteArray &metadata)
576void Media::uploadImage(
const QByteArray &image)
584void Media::processNewBLOB(
IBLOB * bp)
591 if (Options::ekosLiveImageTransfer() ==
false || m_sendBlobs ==
false)
595 sendView(view,
"+A");
597 sendView(view,
"+F");
599 sendView(view,
"+G");
601 sendView(view,
"+D");
Align class handles plate-solving and polar alignment measurement and correction using astrometry....
bool loadAndSlew(const QByteArray &image, const QString &extension)
DBUS interface function.
INDIListener is responsible for creating ISD::GDInterface generic devices as new devices arrive from ...
static KStars * Instance()
Provides all necessary information about an object in the sky: its coordinates, name(s),...
The sky coordinates of a point in the sky.
Generic record interfaces and implementations.
GeoCoordinates geo(const QVariant &location)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QStringView level(QStringView ifopt)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
QString name(StandardShortcut id)
QByteArray left(qsizetype len) const const
QByteArray mid(qsizetype pos, qsizetype len) const const
QByteArray toHex(char separator) const const
QByteArray hash(QByteArrayView data, Algorithm method)
void setCompression(int compression)
void setDevice(QIODevice *device)
bool write(const QImage &image)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QByteArray toJson(JsonFormat format) const const
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QByteArray toLatin1() const const
QString toLower() const const
QTextStream & center(QTextStream &stream)
QFuture< T > run(Function function,...)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString(StringFormat mode) const const