Skip to content

Commit

Permalink
Merge pull request #741 from zarath/feature/fix_device_settings
Browse files Browse the repository at this point in the history
fix crash on device settings
  • Loading branch information
zarath authored Dec 10, 2024
2 parents bfd069c + 0f0e50f commit 6f236c2
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 273 deletions.
18 changes: 9 additions & 9 deletions src/NanoVNASaver/Analysis/AntennaAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,25 @@ class MagLoopAnalysis(VSWRAnalysis):
"""

max_dips_shown = 1
MAX_DIPS_SHOWN: int = 1

vswr_bandwith_value = 2.56 # -3 dB ?!?
bandwith = 25000 # 25 kHz
vswr_bandwith_value: float = 2.56 # -3 dB ?!?
bandwith: int = 25000 # 25 kHz

def __init__(self, app):
def __init__(self, app) -> None:
# app.sweep_control.get_start() return -1 ?!?
# will populate first runAnalysis()
self.min_freq = None # app.sweep_control.get_start()
self.max_freq = None # app.sweep_control.get_end()
self.vswr_limit_value = self.vswr_bandwith_value
self.min_freq: int = 0 # app.sweep_control.get_start()
self.max_freq: int = 0 # app.sweep_control.get_end()
self.vswr_limit_value: float = self.vswr_bandwith_value

super().__init__(app)

def runAnalysis(self):
def runAnalysis(self) -> None:
super().runAnalysis()
new_start = self.app.sweep_control.get_start()
new_end = self.app.sweep_control.get_end()
if self.min_freq is None:
if not self.min_freq:
self.min_freq = new_start
self.max_freq = new_end
logger.debug(
Expand Down
15 changes: 10 additions & 5 deletions src/NanoVNASaver/Analysis/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
from typing import TYPE_CHECKING

from PyQt6 import QtWidgets

if TYPE_CHECKING:
from NanoVNASaver.NanoVNASaver import NanoVNASaver as NanoVNA


logger = logging.getLogger(__name__)

CUTOFF_VALS: tuple[float, ...] = (3.0, 6.0, 10.0, 20.0, 60.0)
Expand All @@ -33,7 +38,7 @@ def __init__(self):


class Analysis:
def __init__(self, app: QtWidgets.QWidget):
def __init__(self, app: "NanoVNA") -> None:
self.app = app
self.label: dict[str, QtWidgets.QLabel] = {
"titel": QtWidgets.QLabel(),
Expand All @@ -46,15 +51,15 @@ def __init__(self, app: QtWidgets.QWidget):
def widget(self) -> QtWidgets.QWidget:
return self._widget

def runAnalysis(self):
def runAnalysis(self) -> None:
pass

def reset(self):
def reset(self) -> None:
for label in self.label.values():
label.clear()

def set_result(self, text):
def set_result(self, text) -> None:
self.label["result"].setText(text)

def set_titel(self, text):
def set_titel(self, text) -> None:
self.label["titel"].setText(text)
14 changes: 9 additions & 5 deletions src/NanoVNASaver/Analysis/VSWRAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,25 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
from typing import TYPE_CHECKING

from PyQt6 import QtWidgets

import NanoVNASaver.AnalyticTools as At
from NanoVNASaver.Analysis.Base import Analysis, QHLine
from NanoVNASaver.Formatting import format_frequency, format_vswr

if TYPE_CHECKING:
from NanoVNASaver.NanoVNASaver import NanoVNASaver as NanoVNA

logger = logging.getLogger(__name__)


class VSWRAnalysis(Analysis):
max_dips_shown = 3
vswr_limit_value = 1.5
MAX_DIPS_SHOWN: int = 3
vswr_limit_value: float = 1.5

def __init__(self, app):
def __init__(self, app: "NanoVNA") -> None:
super().__init__(app)

self._widget = QtWidgets.QWidget()
Expand All @@ -55,7 +59,7 @@ def __init__(self, app):

self.minimums: list[int] = []

def runAnalysis(self):
def runAnalysis(self) -> None:
if not self.app.data.s11:
return
s11 = self.app.data.s11
Expand All @@ -64,7 +68,7 @@ def runAnalysis(self):
threshold = self.input_vswr_limit.value()

minima = sorted(At.minima(data, threshold), key=lambda i: data[i])[
: VSWRAnalysis.max_dips_shown
: VSWRAnalysis.MAX_DIPS_SHOWN
]
self.minimums = minima

Expand Down
5 changes: 3 additions & 2 deletions src/NanoVNASaver/Controls/SerialControl.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ def connect_device(self):
self.btn_toggle.setText("Disconnect")
self.btn_toggle.repaint()

frequencies = self.app.vna.readFrequencies()
if not frequencies:
try:
frequencies = self.app.vna.read_frequencies()
except ValueError:
logger.warning("No frequencies read")
return
logger.info(
Expand Down
2 changes: 1 addition & 1 deletion src/NanoVNASaver/Defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import dataclasses as DC
import dataclasses as DC # noqa: N812
import logging
from ast import literal_eval

Expand Down
2 changes: 1 addition & 1 deletion src/NanoVNASaver/Formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def format_gain(val: float, invert: bool = False) -> str:


def format_q_factor(val: float, allow_negative: bool = False) -> str:
if (not allow_negative and val < 0) or abs(val > 10000.0):
if (not allow_negative and val < 0) or abs(val > 10000.0): # noqa: PLR2004
return "\N{INFINITY}"
return str(SITools.Value(val, fmt=FMT_Q_FACTOR))

Expand Down
2 changes: 1 addition & 1 deletion src/NanoVNASaver/Hardware/Hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def get_interfaces() -> list[Interface]:
# serial like usb interfaces
for d in list_ports.comports():
if platform.system() == "Windows" and d.vid is None:
d = _fix_v2_hwinfo(d)
d = _fix_v2_hwinfo(d) # noqa: PLW2901
if not (typename := usb_typename(d)):
continue
logger.debug(
Expand Down
12 changes: 6 additions & 6 deletions src/NanoVNASaver/Hardware/NanoVNA.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _get_running_frequencies(self):
logger.debug("Reading values: frequencies")
try:
frequencies = super().readValues("frequencies")
return frequencies[0], frequencies[-1]
return int(frequencies[0].real), int(frequencies[-1].real)
except Exception as e:
logger.warning("%s reading frequencies", e)
logger.info("falling back to generic")
Expand Down Expand Up @@ -122,18 +122,18 @@ def read_features(self):
self.features.add("Scan command")
self.sweep_method = "scan"

def readFrequencies(self) -> list[int]:
def read_frequencies(self) -> list[int]:
logger.debug("readFrequencies: %s", self.sweep_method)
if self.sweep_method != "scan_mask":
return super().readFrequencies()
return super().read_frequencies()
return [
int(line)
for line in self.exec_command(
f"scan {self.start} {self.stop} {self.datapoints} 0b001"
)
]

def readValues(self, value) -> list[str]:
def readValues(self, value) -> list[complex]:
if self.sweep_method != "scan_mask":
return super().readValues(value)
logger.debug("readValue with scan mask (%s)", value)
Expand All @@ -144,9 +144,9 @@ def readValues(self, value) -> list[str]:
for line in self.exec_command(
f"scan {self.start} {self.stop} {self.datapoints} 0b110"
):
data = line.split()
d = list(map(float, line.split()))
self._sweepdata.append(
(f"{data[0]} {data[1]}", f"{data[2]} {data[3]}")
(complex(d[0], d[1]), complex(d[2], d[3]))
)
if value == "data 0":
return [x[0] for x in self._sweepdata]
Expand Down
2 changes: 1 addition & 1 deletion src/NanoVNASaver/Hardware/NanoVNA_F.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
logger = logging.getLogger(__name__)


class NanoVNA_F(NanoVNA):
class NanoVNA_F(NanoVNA): # noqa: N801
name = "NanoVNA-F"
screenwidth = 800
screenheight = 480
Expand Down
22 changes: 10 additions & 12 deletions src/NanoVNASaver/Hardware/NanoVNA_V2.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
}


class NanoVNA_V2(VNA):
class NanoVNA_V2(VNA): # noqa: N801
name = "NanoVNA-V2"
valid_datapoints = (101, 11, 51, 201, 301, 501, 1023)
screenwidth = 320
Expand All @@ -85,7 +85,7 @@ def __init__(self, iface: Interface):
sleep(WRITE_SLEEP)

# firmware major version of 0xff indicates dfu mode
if self.version.major == 0xFF:
if self.version.major == 0xFF: # noqa: PLR2004
raise IOError("Device is in DFU mode")

if "S21 hack" in self.features:
Expand Down Expand Up @@ -130,7 +130,7 @@ def readFirmware(self) -> str:
logger.debug("readFirmware: %s", result)
return result

def readFrequencies(self) -> list[int]:
def read_frequencies(self) -> list[int]:
return [
int(self.sweepStartHz + i * self.sweepStepHz)
for i in range(self.datapoints)
Expand Down Expand Up @@ -158,7 +158,7 @@ def _read_pointstoread(self, pointstoread, arr) -> None:

logger.debug("Freq index to: %i", freq_index)

def readValues(self, value) -> list[str]:
def readValues(self, value) -> list[complex]:
# Actually grab the data only when requesting channel 0.
# The hardware will return all channels which we will store.
if value == "data 0":
Expand Down Expand Up @@ -222,9 +222,7 @@ def readValues(self, value) -> list[str]:
self._sweepdata = self._sweepdata[1:]

idx = 1 if value == "data 1" else 0
return [
f"{str(x[idx].real)} {str(x[idx].imag)}" for x in self._sweepdata
]
return [x[idx] for x in self._sweepdata]

def resetSweep(self, start: int, stop: int):
self.setSweep(start, stop)
Expand All @@ -237,7 +235,7 @@ def _read_version(self, cmd_0: int, cmd_1: int):
sleep(2.0) # could fix bug #585 but shoud be done
# in a more predictive way
resp = self.serial.read(2)
if len(resp) != 2:
if len(resp) != 2: # noqa: PLR2004
logger.error("Timeout reading version registers. Got: %s", resp)
raise IOError("Timeout reading version registers")
return Version(f"{resp[0]}.0.{resp[1]}")
Expand Down Expand Up @@ -288,7 +286,7 @@ def _updateSweep(self):
sleep(WRITE_SLEEP)

def setTXPower(self, freq_range, power_desc):
if freq_range[0] != 140e6:
if freq_range[0] != 140e6: # noqa: PLR2004
raise ValueError("Invalid TX power frequency range")
# 140MHz..max => ADF4350
self._set_register(0x42, _ADF4350_TXPOWER_DESC_REV_MAP[power_desc], 1)
Expand All @@ -297,11 +295,11 @@ def _set_register(self, addr, value, size):
packet = b""
if size == 1:
packet = pack("<BBB", _CMD_WRITE, addr, value)
elif size == 2:
elif size == 2: # noqa: PLR2004
packet = pack("<BBH", _CMD_WRITE2, addr, value)
elif size == 4:
elif size == 4: # noqa: PLR2004
packet = pack("<BBI", _CMD_WRITE4, addr, value)
elif size == 8:
elif size == 8: # noqa: PLR2004
packet = pack("<BBQ", _CMD_WRITE8, addr, value)
self.serial.write(packet)
logger.debug("set register %02x (size %d) to %x", addr, size, value)
19 changes: 9 additions & 10 deletions src/NanoVNASaver/Hardware/TinySA.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _get_running_frequencies(self):
logger.debug("Reading values: frequencies")
try:
frequencies = super().readValues("frequencies")
return frequencies[0], frequencies[-1]
return int(frequencies[0]), int(frequencies[-1])
except Exception as e:
logger.warning("%s reading frequencies", e)
logger.info("falling back to generic")
Expand Down Expand Up @@ -108,27 +108,26 @@ def setSweep(self, start, stop):
list(self.exec_command(f"sweep {start} {stop} {self.datapoints}"))
list(self.exec_command("trigger auto"))

def readFrequencies(self) -> list[int]:
def read_frequencies(self) -> list[int]:
logger.debug("readFrequencies")
return [int(line) for line in self.exec_command("frequencies")]
return [int(line.real) for line in self.exec_command("frequencies")]

def readValues(self, value) -> list[str]:
def conv2float(data: str) -> float:
def readValues(self, value) -> list[complex]:
def conv2complex(data: str) -> complex:
try:
return 10 ** (float(data.strip()) / 20)
return complex(10 ** (float(data.strip()) / 20), 0.0)
except ValueError:
return 0.0
return complex(0.0, 0.0)

logger.debug("Read: %s", value)
if value == "data 0":
self._sweepdata = [
f"{conv2float(line)} 0.0"
for line in self.exec_command("data 0")
conv2complex(line) for line in self.exec_command("data 0")
]
return self._sweepdata


class TinySA_Ultra(TinySA):
class TinySA_Ultra(TinySA): # noqa: N801
name = "tinySA Ultra"
screenwidth = 480
screenheight = 320
Expand Down
12 changes: 7 additions & 5 deletions src/NanoVNASaver/Hardware/VNA.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ def set_bandwidth(self, bandwidth: int):
raise IOError(f"set_bandwith({bandwidth}: {result}")
self.bandwidth = bandwidth

def readFrequencies(self) -> list[int]:
return [int(f) for f in self.readValues("frequencies")]
def read_frequencies(self) -> list[int]:
return [int(f.real) for f in self.readValues("frequencies")]

def resetSweep(self, start: int, stop: int):
pass

def _get_running_frequencies(self):
def _get_running_frequencies(self) -> tuple[int, int]:
"""
If possible, read frequencies already running
if not return default values
Expand Down Expand Up @@ -200,9 +200,11 @@ def readFirmware(self) -> str:
logger.debug("result:\n%s", result)
return result

def readValues(self, value) -> list[str]:
def readValues(self, value) -> list[complex]:
logger.debug("VNA reading %s", value)
result = list(self.exec_command(value))
result = [
complex(*map(float, s.split())) for s in self.exec_command(value)
]
logger.debug("VNA done reading %s (%d values)", value, len(result))
return result

Expand Down
4 changes: 2 additions & 2 deletions src/NanoVNASaver/Settings/Sweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ def __init__(
end: int = 30000000,
points: int = 101,
segments: int = 1,
properties: "Properties" = Properties(),
properties: "Properties" = None,
):
self._start = start
self._end = end
self._points = points
self._segments = segments
self._properties = properties
self._properties = Properties()
self._lock = Lock()
self.check()
logger.debug("%s", self)
Expand Down
Loading

0 comments on commit 6f236c2

Please sign in to comment.