diff --git a/docker/scripts/install-owrx-tools.sh b/docker/scripts/install-owrx-tools.sh
index faed762a..a95d39d3 100755
--- a/docker/scripts/install-owrx-tools.sh
+++ b/docker/scripts/install-owrx-tools.sh
@@ -56,12 +56,12 @@ cd ..
rm -rf pycsdr-eti
git clone https://github.com/jketterl/csdr-sstv.git
-# latest develop as of 2024-02-13 (initial integration)
-cmakebuild csdr-sstv 3976d9cd22fe04f253e30d843e43c7d6622b5240
+# latest develop as of 2024-02-26 (more metadata)
+cmakebuild csdr-sstv 9201b9dd362e4da3d1bf5cd8b7c674c0b0e2b633
git clone https://github.com/jketterl/pycsdr-sstv.git
cd pycsdr-sstv
-# latest develop as of 2024-02-12 (initial integration)
+# latest develop as of 2024-02-22 (initial integration)
git checkout b91eeab3673759ec0521f7d1e1d92588d7c7f292
./setup.py install
cd ..
diff --git a/htdocs/lib/MessagePanel.js b/htdocs/lib/MessagePanel.js
index bbe366af..a90ca6bb 100644
--- a/htdocs/lib/MessagePanel.js
+++ b/htdocs/lib/MessagePanel.js
@@ -821,6 +821,10 @@ SstvMessagePanel.prototype = Object.create(MessagePanel.prototype);
SstvMessagePanel.prototype.render = function() {
$(this.el).append($(
'
' +
+ '
' +
'
' +
'' +
'
' +
@@ -836,7 +840,13 @@ SstvMessagePanel.prototype.supportsMessage = function(message) {
SstvMessagePanel.prototype.pushMessage = function(message) {
if ('vis' in message) {
- console.info("got vis: " + message.vis);
+ $(this.el).find('.sstv-vis').text('VIS: ' + message.vis);
+ }
+ if ('meta' in message) {
+ var str = Object.entries(message.meta).map(function(entry) {
+ return entry[0] + ': ' + entry[1];
+ }).join('; ');
+ $(this.el).find('.sstv-meta').text(str);
}
if ('resolution' in message) {
console.info("got resolution: ", message.resolution);
@@ -863,6 +873,7 @@ SstvMessagePanel.prototype.pushMessage = function(message) {
SstvMessagePanel.prototype.clearMessages = function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.currentLine = 0;
+ $(this.el).find('.sstv-information > div').empty();
};
$.fn.sstvMessagePanel = function() {
diff --git a/owrx/sstv/__init__.py b/owrx/sstv/__init__.py
index 086f1d6b..3b7eb2bd 100644
--- a/owrx/sstv/__init__.py
+++ b/owrx/sstv/__init__.py
@@ -3,7 +3,7 @@ from csdr.module import ThreadModule
import pickle
import struct
from abc import ABCMeta, abstractmethod
-from typing import List
+from typing import List, Dict
import logging
@@ -16,18 +16,29 @@ class ImageParser(ThreadModule, metaclass=ABCMeta):
lines = 0
pixels = 0
synced = False
+ headerFormat = "@hhhfff"
+ headerSize = struct.calcsize(headerFormat)
while self.doRun:
data = self.reader.read()
if data is None:
self.doRun = False
else:
stash += data
- while not synced and len(stash) >= 10:
+ while not synced and len(stash) >= 4 + headerSize:
synced = stash[:4] == bytes(b"SYNC")
if synced:
- (vis, pixels, lines) = struct.unpack("hhh", stash[4:10])
- stash = stash[10:]
- self.startImage(vis, pixels, lines)
+ (vis, pixels, lines, error, offset, visError) = struct.unpack(headerFormat, stash[4:4 + headerSize])
+ stash = stash[4 + headerSize:]
+ self.startImage(
+ vis,
+ pixels,
+ lines,
+ {
+ "error": error,
+ "offset": offset,
+ "visError": visError,
+ }
+ )
else:
# go search for sync... byte by byte.
stash = stash[1:]
@@ -44,7 +55,7 @@ class ImageParser(ThreadModule, metaclass=ABCMeta):
return Format.CHAR
@abstractmethod
- def startImage(self, vis: int, pixels: int, lines: int) -> None:
+ def startImage(self, vis: int, pixels: int, lines: int, meta: Dict) -> None:
pass
@abstractmethod
@@ -60,7 +71,7 @@ class SstvParser(ImageParser):
def getOutputFormat(self) -> Format:
return Format.CHAR
- def startImage(self, vis: int, pixels: int, lines: int) -> None:
+ def startImage(self, vis: int, pixels: int, lines: int, meta: Dict) -> None:
logger.debug("got image data: VIS = %i resolution: %i x %i", vis, pixels, lines)
message = {
"mode": "SSTV",
@@ -68,7 +79,8 @@ class SstvParser(ImageParser):
"resolution": {
"width": pixels,
"height": lines
- }
+ },
+ "meta": meta,
}
self.writer.write(pickle.dumps(message))
diff --git a/owrx/sstv/png.py b/owrx/sstv/png.py
index 0aa657b1..89c4fd22 100644
--- a/owrx/sstv/png.py
+++ b/owrx/sstv/png.py
@@ -1,6 +1,6 @@
from pycsdr.types import Format
from owrx.sstv import ImageParser
-from typing import List
+from typing import List, Dict
from io import BytesIO
from owrx.reporting import ReportingEngine
import png
@@ -12,17 +12,19 @@ class PngAdapter(ImageParser):
self.vis = 0
self.pixels = 0
self.lines = 0
+ self.meta = None
self.image_data = []
super().__init__()
def getOutputFormat(self) -> Format:
return Format.CHAR
- def startImage(self, vis: int, pixels: int, lines: int) -> None:
+ def startImage(self, vis: int, pixels: int, lines: int, meta: Dict) -> None:
self.image_data = []
self.vis = vis
self.pixels = pixels
self.lines = lines
+ self.meta = meta
def processLine(self, line: List[int]) -> None:
self.image_data += [line]
@@ -38,6 +40,7 @@ class PngAdapter(ImageParser):
"mode": "SSTV",
"vis": self.vis,
"image": base64.b64encode(image_binary).decode('ascii'),
+ "meta": self.meta,
}
ReportingEngine.getSharedInstance().spot(spot)
f.close()