Compare commits

...

123 commits

Author SHA1 Message Date
codefactor-io ceb06cf834
[CodeFactor] Apply fixes to commit a6eec88 2024-02-21 16:47:10 +00:00
DJ2LS cf06bbffea Prettified Code! 2024-02-21 16:46:47 +00:00
DJ2LS a6eec88337
Merge pull request #656 from DJ2LS/develop
several arq related fixes
2024-02-21 17:46:32 +01:00
DJ2LS f33222794b
Merge pull request #657 from DJ2LS/dev-radio-control
adjusted radio control and some more fixes
2024-02-21 17:19:50 +01:00
DJ2LS 9db78d1031 arq adjustments 2024-02-21 17:05:28 +01:00
DJ2LS 0349cf1b7c callsign related adustments... 2024-02-21 16:55:45 +01:00
DJ2LS fbcc49019f fixed missing updater 2024-02-21 16:52:26 +01:00
DJ2LS 8b65b6240b added updater 2024-02-21 11:18:57 +01:00
DJ2LS 98d8812571 fixed modals in background 2024-02-21 11:10:24 +01:00
DJ2LS c42ac793b9 added error check to gui 2024-02-21 11:01:24 +01:00
DJ2LS 2156a8fa8f added updater placeholder... 2024-02-20 11:05:57 +01:00
DJ2LS ba5fbd3a71 introduced radioHandler.ts 2024-02-20 10:05:13 +01:00
DJ2LS 5c232a2165 forgot a 0 ... 2024-02-20 09:52:26 +01:00
DJ2LS 31a93b3183 adjusted state fetching and rf power setting 2024-02-20 09:39:47 +01:00
DJ2LS fea294b26f fixed radio api 2024-02-20 09:13:34 +01:00
DJ2LS f76dc5da14 first attempt fixing radio mode related problems by separating parameters 2024-02-20 08:09:05 +01:00
DJ2LS f1971cdf4f Merge remote-tracking branch 'origin/develop' into develop 2024-02-19 20:08:11 +01:00
DJ2LS 1337a4a0c8 fixed more tests 2024-02-19 20:08:05 +01:00
DJ2LS 347a916a34
Merge pull request #645 from DJ2LS/dependabot/npm_and_yarn/gui/develop/socket.io-4.7.4 2024-02-19 11:46:05 +01:00
DJ2LS b1a1a40e97
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/socket.io-4.7.4 2024-02-19 11:46:00 +01:00
DJ2LS 4405293a90
Merge pull request #644 from DJ2LS/dependabot/npm_and_yarn/gui/develop/vite-plugin-electron-0.28.2 2024-02-19 11:45:50 +01:00
DJ2LS d95bea09a8
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/vite-plugin-electron-0.28.2 2024-02-19 11:45:43 +01:00
DJ2LS b7563040ef only retry first result 2024-02-19 11:06:15 +01:00
DJ2LS 30de19f729 possibly fixed repeating message 2024-02-19 10:59:53 +01:00
DJ2LS 2c24545e68 possibly fixed repeating message 2024-02-19 10:53:44 +01:00
DJ2LS 35276b01ef improved message tests which went stuck 2024-02-19 08:37:16 +01:00
DJ2LS 10be8db7d0 improved arq tests which went stuck 2024-02-19 08:27:40 +01:00
DJ2LS 1cfae172bb
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/socket.io-4.7.4 2024-02-19 07:48:03 +01:00
DJ2LS 4a3a0e4893
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/vite-plugin-electron-0.28.2 2024-02-19 07:47:59 +01:00
DJ2LS fde3de12d6
Merge pull request #643 from DJ2LS/dependabot/npm_and_yarn/gui/develop/vitejs/plugin-vue-5.0.4 2024-02-19 07:44:57 +01:00
DJ2LS b002e7136e
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/vitejs/plugin-vue-5.0.4 2024-02-19 07:44:10 +01:00
dependabot[bot] 25bd486f8e
Bump vite-plugin-electron from 0.28.0 to 0.28.2 in /gui
Bumps [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron) from 0.28.0 to 0.28.2.
- [Release notes](https://github.com/electron-vite/vite-plugin-electron/releases)
- [Changelog](https://github.com/electron-vite/vite-plugin-electron/blob/main/CHANGELOG.md)
- [Commits](https://github.com/electron-vite/vite-plugin-electron/compare/v0.28.0...v0.28.2)

---
updated-dependencies:
- dependency-name: vite-plugin-electron
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 06:24:03 +00:00
DJ2LS 9969b214d9
Merge pull request #642 from DJ2LS/dependabot/npm_and_yarn/gui/develop/eslint-plugin-prettier-5.1.3 2024-02-19 07:23:31 +01:00
DJ2LS 084c1143ee
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/eslint-plugin-prettier-5.1.3 2024-02-19 07:23:22 +01:00
DJ2LS 67a3ab31e7
Merge pull request #654 from DJ2LS/dependabot/npm_and_yarn/gui/develop/vite-5.1.3 2024-02-19 07:22:15 +01:00
DJ2LS 91941eec7b
Merge branch 'develop' into dependabot/npm_and_yarn/gui/develop/vite-5.1.3 2024-02-19 07:22:03 +01:00
Mashintime 6db6c486a3 Remove print (accidentally committed) 2024-02-18 15:46:40 -05:00
Mashintime d87579f9ac Merge branch 'develop' of github.com:DJ2LS/FreeDATA into develop 2024-02-18 15:39:08 -05:00
Mashintime ee6ca66602
Merge pull request #655 from DJ2LS/dev-message-auto-repeat
message auto repeat
2024-02-18 15:37:37 -05:00
Mashintime 0213e538fa
Merge pull request #653 from DJ2LS/dev-arq
arq adjustments
2024-02-18 15:37:04 -05:00
Mashintime 796d1c0566 Only restart modem if config is valid 2024-02-18 15:34:10 -05:00
Mashintime 47242fb33e Remove duplicate setting 2024-02-18 15:33:42 -05:00
Mashintime 70228054fd Remove unused setting 2024-02-18 15:33:29 -05:00
DJ2LS f8bff53eae updated example config and typo 2024-02-18 21:31:08 +01:00
DJ2LS 2bfc8c345a Merge remote-tracking branch 'origin/dev-arq' into dev-message-auto-repeat 2024-02-18 21:19:21 +01:00
DJ2LS 7d33c0aad9 Merge remote-tracking branch 'origin/dev-arq' into dev-arq 2024-02-18 21:18:37 +01:00
DJ2LS dbc959d06e added config related parts 2024-02-18 21:15:33 +01:00
DJ2LS 3a84ec0bbb Merge remote-tracking branch 'origin/dev-arq' into dev-message-auto-repeat 2024-02-18 21:11:06 +01:00
DJ2LS 7a09f94767 added config related parts 2024-02-18 21:08:14 +01:00
DJ2LS 25dedfde6c Merge remote-tracking branch 'origin/develop' into dev-message-auto-repeat 2024-02-18 20:38:55 +01:00
DJ2LS e90d1f7716 adjusted config 2024-02-18 20:31:01 +01:00
Mashintime 273914d714 Extra serial port in config.py 2024-02-18 13:57:53 -05:00
Mashintime 44d24123b1 Remove enable_fft from gui settingstore 2024-02-18 13:57:16 -05:00
Mashintime d7bd9c86a8 Merge branch 'develop' of github.com:DJ2LS/FreeDATA into develop 2024-02-18 12:43:09 -05:00
DJ2LS 303ac0d6ef
Merge branch 'develop' into dev-arq 2024-02-18 16:16:24 +01:00
dependabot[bot] b52d55285c
Bump vite from 5.0.12 to 5.1.3 in /gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.12 to 5.1.3.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.1.3/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-18 14:08:57 +00:00
DJ2LS 5ef97720b0
Merge pull request #652 from DJ2LS/dev-update-config
auto update server config
2024-02-18 15:07:33 +01:00
DJ2LS c329070606
Merge pull request #651 from DJ2LS/more-rigctl
Rigctl argument tweaks
2024-02-18 15:07:15 +01:00
DJ2LS 7f86ab2ece arq adjustments and attempt fixing tests 2024-02-18 15:06:13 +01:00
Mashintime 5bee82a17c Further adjustment 2024-02-17 16:57:54 -05:00
DJ2LS 657a6a8967 default values as list 2024-02-17 20:45:51 +01:00
DJ2LS 404585ebe0 auto update server config 2024-02-17 20:42:07 +01:00
Mashintime c26f9cb9ba Incr Next Version 2024-02-17 12:55:10 -05:00
Mashintime 7eaac1cc29 Fix typos/remove rts 2024-02-17 11:03:59 -05:00
Mashintime a07249213e
Merge branch 'develop' into more-rigctl 2024-02-17 10:53:04 -05:00
Mashintime b69e485f10 Merge branch 'develop' of github.com:DJ2LS/FreeDATA into develop 2024-02-17 10:48:44 -05:00
Mashintime fc055671cb Adjustments to rigctld arguments 2024-02-17 10:41:56 -05:00
DJ2LS 916c2a4a63 delete beacons older than 2 days 2024-02-17 10:41:33 -05:00
DJ2LS 8d47d4890e removed rigctld typo 2024-02-17 10:41:33 -05:00
DJ2LS b569cbc315 adjusted a rigctld command 2024-02-17 10:41:33 -05:00
DJ2LS 4f50b802ac adjusted state manager in data type handler 2024-02-17 10:41:33 -05:00
DJ2LS 0e1986b2da removed possibly obsolete arq state at wrong position 2024-02-17 10:41:33 -05:00
DJ2LS 390817caa7 repeat message when beacon received 2024-02-16 11:02:10 +01:00
DJ2LS 11a27bcbd7
Merge pull request #650 from DJ2LS/dev-arq 2024-02-14 22:57:32 +01:00
DJ2LS 877b517b72 delete beacons older than 2 days 2024-02-14 16:45:19 +01:00
DJ2LS 9a8ebfef77 removed rigctld typo 2024-02-14 16:29:18 +01:00
DJ2LS b017f39133 adjusted a rigctld command 2024-02-14 16:20:00 +01:00
DJ2LS 6dd78bf8fc adjusted state manager in data type handler 2024-02-14 09:27:20 +01:00
DJ2LS fffc59b0a6 removed possibly obsolete arq state at wrong position 2024-02-14 09:13:39 +01:00
Mashintime 12d1010da9 Bump version 2024-02-12 16:17:24 -05:00
Mashintime 3b505d24f2
Merge pull request #648 from DJ2LS/develop
Develop
2024-02-12 16:14:46 -05:00
Mashintime fc9e848f1f
Merge branch 'main' into develop 2024-02-12 16:14:20 -05:00
DJ2LS f437b2a01b
Merge pull request #647 from DJ2LS/rigctld-win
Internal rigctld tweaks for windows users
2024-02-11 21:38:24 +01:00
DJ2LS 0738fe1454 removed 32bit hamlib build 2024-02-11 20:59:29 +01:00
Mashintime 321dda3fd9 Include custom args when starting rigctld 2024-02-11 13:09:51 -05:00
Mashintime 37bc01e426 Check Program Files on Windows for Hamlib 2024-02-11 13:07:48 -05:00
Mashintime f11c61c8a6 Remove default settings from example config 2024-02-11 13:05:03 -05:00
dependabot[bot] acb2bb4e9b
Bump socket.io from 4.7.2 to 4.7.4 in /gui
Bumps [socket.io](https://github.com/socketio/socket.io) from 4.7.2 to 4.7.4.
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/compare/4.7.2...4.7.4)

---
updated-dependencies:
- dependency-name: socket.io
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-11 10:20:01 +00:00
dependabot[bot] 910690178e
Bump @vitejs/plugin-vue from 5.0.3 to 5.0.4 in /gui
Bumps [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) from 5.0.3 to 5.0.4.
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@5.0.4/packages/plugin-vue)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-vue"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-11 10:19:32 +00:00
dependabot[bot] 950eab71fe
Bump eslint-plugin-prettier from 5.0.1 to 5.1.3 in /gui
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.1 to 5.1.3.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.0.1...v5.1.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-11 10:19:21 +00:00
DJ2LS 38c54b575a
Merge pull request #640 from DJ2LS/develop
start rigctld automatically & fix for missing gui config
2024-02-11 11:18:31 +01:00
DJ2LS c15e489b1c
Merge pull request #630 from DJ2LS/dependabot/npm_and_yarn/gui/develop/eslint-plugin-n-16.6.2
Bump eslint-plugin-n from 16.1.0 to 16.6.2 in /gui
2024-02-11 10:07:35 +01:00
DJ2LS 923ab36668
Merge pull request #631 from DJ2LS/dependabot/npm_and_yarn/gui/develop/vitest-1.2.2
Bump vitest from 1.0.2 to 1.2.2 in /gui
2024-02-11 10:07:26 +01:00
DJ2LS 21ab92f873
Merge pull request #632 from DJ2LS/dependabot/npm_and_yarn/gui/develop/eslint-config-standard-with-typescript-43.0.1
Bump eslint-config-standard-with-typescript from 43.0.0 to 43.0.1 in /gui
2024-02-11 10:07:19 +01:00
DJ2LS 75c5227536
Merge pull request #634 from DJ2LS/dependabot/npm_and_yarn/gui/develop/typescript-eslint/eslint-plugin-6.21.0
Bump @typescript-eslint/eslint-plugin from 6.19.1 to 6.21.0 in /gui
2024-02-11 10:07:07 +01:00
DJ2LS fa9d684853
Merge pull request #635 from DJ2LS/dependabot/npm_and_yarn/gui/develop/electron-28.2.2
Bump electron from 28.1.3 to 28.2.2 in /gui
2024-02-11 10:07:00 +01:00
DJ2LS a0525ef01b adjusted dependabot 2024-02-11 10:06:47 +01:00
DJ2LS bb668a1ac9 fixed control check 2024-02-11 10:00:57 +01:00
dependabot[bot] 8332690c67
Bump electron from 28.1.3 to 28.2.2 in /gui
Bumps [electron](https://github.com/electron/electron) from 28.1.3 to 28.2.2.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v28.1.3...v28.2.2)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-11 08:58:09 +00:00
DJ2LS 139bdc7699 version update 2024-02-11 09:57:07 +01:00
DJ2LS 2ccabc28bc
Merge pull request #639 from DJ2LS/dev-start-rigctld-process
start rigctld from local binary
2024-02-11 09:56:37 +01:00
codefactor-io 8525a7a321
[CodeFactor] Apply fixes 2024-02-11 08:55:56 +00:00
DJ2LS 045cb38a63 fixed healthcheck 2024-02-11 09:54:18 +01:00
DJ2LS 9734ce9a1c fixed healthcheck 2024-02-11 09:21:08 +01:00
DJ2LS 64e5e35b6f added internal/external hamlib 2024-02-11 09:17:52 +01:00
DJ2LS c3d558a07a
Merge pull request #638 from arodland/patch-1
fix loading default config
2024-02-11 09:02:29 +01:00
DJ2LS a955d45518 adjusted settings 2024-02-11 08:48:49 +01:00
Andrew Rodland 7099d2e379
fix loading default config
without this change, if the user doesn't have a valid config on disk, they just get a white screen on startup due to `nconf.required` throwing an exception.
2024-02-10 23:13:53 -05:00
DJ2LS 5093abc1dc use system wide path as well for lookup 2024-02-10 21:44:02 +01:00
DJ2LS 704186c3c2 added downloading windwos hamlib releases for nsis 2024-02-10 21:36:14 +01:00
DJ2LS f239a1a3be first attempt using rigctld... 2024-02-10 21:28:07 +01:00
DJ2LS fd63cc7fa7
Merge pull request #637 from DJ2LS/develop
Config related adjustments and build process update
2024-02-10 14:01:21 +01:00
codefactor-io 74d79204ec
[CodeFactor] Apply fixes to commit ec34a69 2024-02-10 12:57:33 +00:00
DJ2LS ec34a690e9 improved gui reconnecting 2024-02-10 13:57:18 +01:00
DJ2LS 17bce4b0db version update 2024-02-10 11:05:55 +01:00
DJ2LS d38b3bc672 reduced explorer interval 2024-02-10 11:05:10 +01:00
DJ2LS c89a809e6d adjusted some default config 2024-02-10 11:02:13 +01:00
DJ2LS d906d9ab5e adjusted artifact names 2024-02-10 07:06:16 +01:00
DJ2LS a6c671e113
Merge pull request #636 from DJ2LS/main-cf-autofix
Apply fixes from CodeFactor
2024-02-08 22:18:41 +01:00
dependabot[bot] 8d7b961f4e
Bump @typescript-eslint/eslint-plugin from 6.19.1 to 6.21.0 in /gui
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.19.1 to 6.21.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.21.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 16:51:39 +00:00
dependabot[bot] 4f3b4b2762
Bump eslint-config-standard-with-typescript in /gui
Bumps [eslint-config-standard-with-typescript](https://github.com/mightyiam/eslint-config-standard-with-typescript) from 43.0.0 to 43.0.1.
- [Release notes](https://github.com/mightyiam/eslint-config-standard-with-typescript/releases)
- [Changelog](https://github.com/mightyiam/eslint-config-standard-with-typescript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mightyiam/eslint-config-standard-with-typescript/compare/v43.0.0...v43.0.1)

---
updated-dependencies:
- dependency-name: eslint-config-standard-with-typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 16:34:47 +00:00
dependabot[bot] 243dc771fd
Bump vitest from 1.0.2 to 1.2.2 in /gui
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 1.0.2 to 1.2.2.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v1.2.2/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 16:34:38 +00:00
dependabot[bot] a99bece107
Bump eslint-plugin-n from 16.1.0 to 16.6.2 in /gui
Bumps [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) from 16.1.0 to 16.6.2.
- [Release notes](https://github.com/eslint-community/eslint-plugin-n/releases)
- [Commits](https://github.com/eslint-community/eslint-plugin-n/compare/16.1.0...16.6.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-n
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 16:34:23 +00:00
45 changed files with 1293 additions and 942 deletions

View file

@ -6,19 +6,19 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
interval: "monthly"
target-branch: "develop"
# Maintain dependencies for npm
- package-ecosystem: "npm"
directory: "/gui"
schedule:
interval: "daily"
interval: "monthly"
target-branch: "develop"
# Maintain dependencies for pip
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
interval: "monthly"
target-branch: "develop"

View file

@ -19,6 +19,14 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements.txt
- uses: robinraju/release-downloader@v1.9
with:
repository: "Hamlib/Hamlib"
fileName: " hamlib-w64-*.zip"
latest: true
extract: true
out-file-path: "modem/lib/hamlib/"
- name: Build binaries
working-directory: modem
run: |

View file

@ -39,7 +39,7 @@
"gatekeeperAssess": false,
"mergeASARs": true,
"x64ArchFiles": "**/*",
"artifactName": "${productName}-Mac-${version}.${ext}"
"artifactName": "${productName}-GUI-Mac-${version}.${ext}"
},
"win": {
"icon": "build/icon.png",
@ -49,7 +49,7 @@
"arch": ["arm64", "x64"]
}
],
"artifactName": "${productName}-Windows-${version}.${ext}"
"artifactName": "${productName}-GUI-Windows-${version}.${ext}"
},
"nsis": {
"oneClick": false,
@ -62,6 +62,6 @@
"target": [
"AppImage"
],
"artifactName": "${productName}-${version}.${ext}"
"artifactName": "${productName}-GUI-Linux-${version}.${ext}"
}
}

View file

@ -2,7 +2,7 @@
"name": "FreeDATA",
"description": "FreeDATA Client application for connecting to FreeDATA server",
"private": true,
"version": "0.13.2-alpha",
"version": "0.13.6-alpha",
"main": "dist-electron/main/index.js",
"scripts": {
"start": "vite",
@ -54,7 +54,7 @@
"noto-color-emoji": "^1.0.1",
"pinia": "2.1.7",
"qth-locator": "2.1.0",
"socket.io": "4.7.2",
"socket.io": "4.7.4",
"uuid": "^9.0.1",
"vue": "3.4.15",
"vue-chartjs": "5.3.0",
@ -62,23 +62,23 @@
},
"devDependencies": {
"@types/nconf": "^0.10.6",
"@typescript-eslint/eslint-plugin": "6.19.1",
"@vitejs/plugin-vue": "5.0.3",
"electron": "28.1.3",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@vitejs/plugin-vue": "5.0.4",
"electron": "28.2.2",
"electron-builder": "24.9.1",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-config-standard-with-typescript": "43.0.0",
"eslint-config-standard-with-typescript": "43.0.1",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-n": "16.1.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-n": "16.6.2",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-vue": "9.20.1",
"typescript": "5.3.3",
"vite": "5.0.12",
"vite-plugin-electron": "0.28.0",
"vite": "5.1.3",
"vite-plugin-electron": "0.28.2",
"vite-plugin-electron-renderer": "0.14.5",
"vitest": "1.0.2",
"vitest": "1.2.2",
"vue": "3.4.15",
"vue-tsc": "1.8.27"
}

View file

@ -123,7 +123,7 @@ const beaconHistogramData = computed(() => ({
<div class="col-9 border-start vh-100 p-0">
<div class="d-flex flex-column vh-100">
<!-- Top Navbar -->
<nav class="navbar sticky-top bg-body-tertiary shadow">
<nav class="navbar sticky-top z-0 bg-body-tertiary shadow">
<div class="input-group mb-0 p-0 w-25">
<button type="button" class="btn btn-outline-secondary" disabled>
Beacons

View file

@ -8,7 +8,7 @@ import "../../node_modules/gridstack/dist/gridstack.min.css";
import { GridStack } from "gridstack";
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
import { setRadioParameters } from "../js/api";
import { setRadioParametersFrequency, setRadioParametersMode, setRadioParametersRFLevel } from "../js/api";
import { saveLocalSettingsToConfig, settingsStore } from "../store/settingsStore";
import active_heard_stations from "./grid/grid_active_heard_stations.vue";
@ -251,14 +251,22 @@ new gridWidget(
//New new widget ID should be 20
];
function updateFrequencyAndApply(frequency) {
state.new_frequency = frequency;
set_radio_parameters();
set_radio_parameter_frequency();
}
function set_radio_parameters(){
setRadioParameters(state.new_frequency, state.mode, state.rf_level);
function set_radio_parameter_frequency(){
setRadioParametersFrequency(state.new_frequency)
}
function set_radio_parameter_mode(){
setRadioParametersMode(state.mode)
}
function set_radio_parameter_rflevel(){
setRadioParametersRFLevel(state.rf_level)
}
@ -358,19 +366,21 @@ onMounted(() => {
setGridEditState();
});
function onChange(event, changeItems) {
// update item position
changeItems.forEach((item) => {
var widget = items.value.find((w) => w.id == item.id);
if (!widget) {
console.error("Widget not found: " + item.id);
return;
if (typeof changeItems !== "undefined"){
// update item position
changeItems.forEach((item) => {
var widget = items.value.find((w) => w.id == item.id);
if (!widget) {
console.error("Widget not found: " + item.id);
return;
}
widget.x = item.x;
widget.y = item.y;
widget.w = item.w;
widget.h = item.h;
});
saveGridLayout();
}
widget.x = item.x;
widget.y = item.y;
widget.w = item.w;
widget.h = item.h;
});
saveGridLayout();
}
function restoreGridLayoutFromConfig(){
//Try to load grid from saved config

View file

@ -1,14 +1,26 @@
<script setup lang="ts">
import { setActivePinia } from "pinia";
import pinia from "../../store/index";
import { setRadioParameters } from "../../js/api";
import {
setRadioParametersFrequency,
setRadioParametersMode,
setRadioParametersRFLevel,
} from "../../js/api";
setActivePinia(pinia);
import { useStateStore } from "../../store/stateStore.js";
const state = useStateStore(pinia);
function set_radio_parameters() {
setRadioParameters(state.frequency, state.mode, state.rf_level);
function set_radio_parameter_frequency() {
setRadioParametersFrequency(state.new_frequency);
}
function set_radio_parameter_mode() {
setRadioParametersMode(state.mode);
}
function set_radio_parameter_rflevel() {
setRadioParametersRFLevel(state.rf_level);
}
</script>
@ -47,18 +59,15 @@ function set_radio_parameters() {
<select
class="form-control"
v-model="state.mode"
@click="set_radio_parameters()"
@click="set_radio_parameter_mode()"
v-bind:class="{
disabled: state.hamlib_status === 'disconnected',
}"
>
<option selected value="">---</option>
<option value="USB">USB</option>
<option value="LSB">LSB</option>
<option value="USB-D">USB-D</option>
<option value="PKTUSB">PKT-U</option>
<option value="PKTLSB">PKT-L</option>
<option value="AM">AM</option>
<option value="FM">FM</option>
<option value="PKTFM">PKTFM</option>
</select>
</div>
</div>
@ -69,7 +78,7 @@ function set_radio_parameters() {
<select
class="form-control"
v-model="state.rf_level"
@click="set_radio_parameters()"
@click="set_radio_parameter_rflevel()"
v-bind:class="{
disabled: state.hamlib_status === 'disconnected',
}"

View file

@ -25,12 +25,7 @@ import { getFreedataMessages } from "../js/api";
<template>
<!-------------------------------- INFO TOASTS ---------------->
<div
aria-live="polite"
aria-atomic="true"
class="position-relative"
style="z-index: 500"
>
<div aria-live="polite" aria-atomic="true" class="position-relative z-3">
<div
class="toast-container position-absolute top-0 end-0 p-3"
id="mainToastContainer"

View file

@ -6,15 +6,27 @@ setActivePinia(pinia);
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
import { setRadioParameters } from "../js/api";
import {
setRadioParametersFrequency,
setRadioParametersMode,
setRadioParametersRFLevel,
} from "../js/api";
function updateFrequencyAndApply(frequency) {
state.new_frequency = frequency;
set_radio_parameters();
set_radio_parameter_frequency();
}
function set_radio_parameters() {
setRadioParameters(state.new_frequency, state.mode, state.rf_level);
function set_radio_parameter_frequency() {
setRadioParametersFrequency(state.new_frequency);
}
function set_radio_parameter_mode() {
setRadioParametersMode(state.mode);
}
function set_radio_parameter_rflevel() {
setRadioParametersRFLevel(state.rf_level);
}
</script>
@ -207,18 +219,14 @@ function set_radio_parameters() {
<select
class="form-control"
v-model="state.mode"
@click="set_radio_parameters()"
@click="set_radio_parameter_mode()"
v-bind:class="{
disabled: state.hamlib_status === 'disconnected',
}"
>
<option value="USB">USB</option>
<option value="LSB">LSB</option>
<option value="USB-D">USB-D</option>
<option value="PKTUSB">PKT-U</option>
<option value="PKTLSB">PKT-L</option>
<option value="AM">AM</option>
<option value="FM">FM</option>
<option value="PKTFM">PKTFM</option>
</select>
</div>
</div>
@ -229,7 +237,7 @@ function set_radio_parameters() {
<select
class="form-control"
v-model="state.rf_level"
@click="set_radio_parameters()"
@click="set_radio_parameter_rflevel()"
v-bind:class="{
disabled: state.hamlib_status === 'disconnected',
}"

View file

@ -1,35 +1,15 @@
<script setup lang="ts">
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { settingsStore as settings} from "../store/settingsStore.js";
import { settingsStore as settings } from "../store/settingsStore.js";
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
function startStopRigctld() {
switch (state.rigctld_started) {
case "stopped":
settings.remote.RADIO.serial_port = (<HTMLInputElement>document.getElementById("hamlib_deviceport")).value;
//startRigctld();
break;
case "running":
//stopRigctld();
// dirty hack for calling this command twice, otherwise modem won't stop rigctld from time to time
//stopRigctld();
break;
default:
}
}
function selectRadioControl() {
// @ts-expect-error
// @ts-expect-error
switch (event.target.id) {
case "list-rig-control-none-list":
settings.remote.RADIO.control = "disabled";
@ -37,6 +17,10 @@ function selectRadioControl() {
case "list-rig-control-rigctld-list":
settings.remote.RADIO.control = "rigctld";
break;
case "list-rig-control-rigctld-list":
settings.remote.RADIO.control = "rigctld_bundle";
break;
case "list-rig-control-tci-list":
settings.remote.RADIO.control = "tci";
break;
@ -47,12 +31,9 @@ function selectRadioControl() {
//saveSettingsToFile();
}
function testHamlib(){
console.log("not yet implemented")
alert("not yet implemented")
function testHamlib() {
console.log("not yet implemented");
alert("not yet implemented");
}
</script>
@ -60,187 +41,181 @@ alert("not yet implemented")
<div class="mb-3">
<div class="card mb-1">
<div class="card-header p-1">
<div class="container">
<div class="row">
<div class="col-1">
<i class="bi bi-projector" style="font-size: 1.2rem"></i>
</div>
<div class="col-4">
<strong class="fs-5">Rig control</strong>
</div>
<div class="col-6">
<div
class="list-group bg-body-tertiary list-group-horizontal w-75"
id="rig-control-list-tab"
role="rig-control-tablist"
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-none-list"
data-bs-toggle="list"
href="#list-rig-control-none"
role="tab"
aria-controls="list-rig-control-none"
v-bind:class="{ active: settings.remote.RADIO.control === 'disabled' }"
@click="selectRadioControl()"
>None</a
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-rigctld-list"
data-bs-toggle="list"
href="#list-rig-control-rigctld"
role="tab"
aria-controls="list-rig-control-rigctld"
v-bind:class="{ active: settings.remote.RADIO.control === 'rigctld' }"
@click="selectRadioControl()"
>Rigctld</a
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-tci-list"
data-bs-toggle="list"
href="#list-rig-control-tci"
role="tab"
aria-controls="list-rig-control-tci"
v-bind:class="{ active: settings.remote.RADIO.control === 'tci' }"
@click="selectRadioControl()"
>TCI</a
>
<div class="container">
<div class="row">
<div class="col-1">
<i class="bi bi-projector" style="font-size: 1.2rem"></i>
</div>
</div>
<div class="col-1 text-end">
<button
type="button"
id="openHelpModalRigControl"
data-bs-toggle="modal"
data-bs-target="#rigcontrolHelpModal"
class="btn m-0 p-0 border-0"
>
<i class="bi bi-question-circle" style="font-size: 1rem"></i>
</button>
</div>
</div>
</div>
</div>
<div class="card-body p-2" style="height: 100px">
<div class="tab-content" id="rig-control-nav-tabContent">
<div
class="tab-pane fade"
v-bind:class="{ 'show active': settings.remote.RADIO.control === 'disabled' }"
id="list-rig-control-none"
role="tabpanel"
aria-labelledby="list-rig-control-none-list"
>
<p class="small">
Modem will not utilize rig control and features will be limited. While
functional; it is recommended to configure hamlib. <br>
Use this setting also for <strong> VOX </strong>
</p>
</div>
<div
class="tab-pane fade"
id="list-rig-control-rigctld"
v-bind:class="{ 'show active': settings.remote.RADIO.control === 'rigctld' }"
role="tabpanel"
aria-labelledby="list-rig-control-rigctld-list"
>
<div class="input-group input-group-sm mb-1">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">Rigctld service</span>
<button
class="btn btn-outline-success"
type="button"
id="hamlib_rigctld_start"
@click="startStopRigctld"
>
Start
</button>
<button
class="btn btn-outline-danger"
type="button"
id="hamlib_rigctld_stop"
@click="startStopRigctld"
>
Stop
</button>
<input
type="text"
class="form-control"
placeholder="Status"
id="hamlib_rigctld_status"
aria-label="State"
aria-describedby="basic-addon1"
v-model="state.rigctld_started"
/>
<button
type="button"
id="testHamlib"
class="btn btn-sm btn-outline-secondary ms-1"
data-bs-placement="bottom"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="true"
@click="testHamlib"
title="Test your hamlib settings and toggle PTT once. Button will become <strong class='text-success'>green</strong> on success and <strong class='text-danger'>red</strong> if fails."
>
PTT Test
</button>
</div>
</div>
</div>
<div
class="tab-pane fade"
id="list-rig-control-tci"
v-bind:class="{ 'show active': settings.remote.RADIO.control === 'tci' }"
role="tabpanel"
aria-labelledby="list-rig-control-tci-list"
>
<div class="input-group input-group-sm mb-1">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">TCI</span>
<span class="input-group-text">Address</span>
<input
type="text"
class="form-control"
placeholder="tci IP"
id="tci_ip"
aria-label="Device IP"
v-model="settings.remote.TCI.tci_ip"
/>
<div class="col-4">
<strong class="fs-5">Rig control</strong>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">Port</span>
<input
type="text"
class="form-control"
placeholder="tci port"
id="tci_port"
aria-label="Device Port"
v-model="settings.remote.TCI.tci_port"
/>
<div class="col-6">
<div
class="list-group bg-body-tertiary list-group-horizontal w-75"
id="rig-control-list-tab"
role="rig-control-tablist"
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-none-list"
data-bs-toggle="list"
href="#list-rig-control-none"
role="tab"
aria-controls="list-rig-control-none"
v-bind:class="{
active: settings.remote.RADIO.control === 'disabled',
}"
@click="selectRadioControl()"
>None</a
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-rigctld-list"
data-bs-toggle="list"
href="#list-rig-control-rigctld"
role="tab"
aria-controls="list-rig-control-rigctld"
v-bind:class="{
active: settings.remote.RADIO.control === 'rigctld',
}"
@click="selectRadioControl()"
>Rigctld</a
>
<a
class="p-1 list-group-item list-group-item-dark list-group-item-action"
id="list-rig-control-tci-list"
data-bs-toggle="list"
href="#list-rig-control-tci"
role="tab"
aria-controls="list-rig-control-tci"
v-bind:class="{
active: settings.remote.RADIO.control === 'tci',
}"
@click="selectRadioControl()"
>TCI</a
>
</div>
</div>
<div class="col-1 text-end">
<button
type="button"
id="openHelpModalRigControl"
data-bs-toggle="modal"
data-bs-target="#rigcontrolHelpModal"
class="btn m-0 p-0 border-0"
>
<i class="bi bi-question-circle" style="font-size: 1rem"></i>
</button>
</div>
</div>
</div>
</div>
<div class="card-body p-2" style="height: 100px">
<div class="tab-content" id="rig-control-nav-tabContent">
<div
class="tab-pane fade"
v-bind:class="{
'show active': settings.remote.RADIO.control === 'disabled',
}"
id="list-rig-control-none"
role="tabpanel"
aria-labelledby="list-rig-control-none-list"
>
<p class="small">
Modem will not utilize rig control and features will be limited.
While functional; it is recommended to configure hamlib. <br />
Use this setting also for <strong> VOX </strong>
</p>
</div>
<div
class="tab-pane fade"
id="list-rig-control-rigctld"
v-bind:class="{
'show active': settings.remote.RADIO.control === 'rigctld',
}"
role="tabpanel"
aria-labelledby="list-rig-control-rigctld-list"
>
<div class="input-group input-group-sm mb-1">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">Rigctld service</span>
<!-- RADIO CONTROL DISABLED -->
<div id="radio-control-disabled"></div>
<input
type="text"
class="form-control"
placeholder="Status"
id="hamlib_rigctld_status"
aria-label="State"
aria-describedby="basic-addon1"
v-model="state.rigctld_started"
/>
<!-- RADIO CONTROL RIGCTLD -->
<div id="radio-control-rigctld"></div>
<!-- RADIO CONTROL TCI-->
<div id="radio-control-tci"></div>
<!-- RADIO CONTROL HELP -->
<div id="radio-control-help">
<!--
<button
type="button"
id="testHamlib"
class="btn btn-sm btn-outline-secondary ms-1"
data-bs-placement="bottom"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="true"
@click="testHamlib"
title="Test your hamlib settings and toggle PTT once. Button will become <strong class='text-success'>green</strong> on success and <strong class='text-danger'>red</strong> if fails."
>
PTT Test
</button>
</div>
</div>
</div>
<div
class="tab-pane fade"
id="list-rig-control-tci"
v-bind:class="{
'show active': settings.remote.RADIO.control === 'tci',
}"
role="tabpanel"
aria-labelledby="list-rig-control-tci-list"
>
<div class="input-group input-group-sm mb-1">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">TCI</span>
<span class="input-group-text">Address</span>
<input
type="text"
class="form-control"
placeholder="tci IP"
id="tci_ip"
aria-label="Device IP"
v-model="settings.remote.TCI.tci_ip"
/>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text">Port</span>
<input
type="text"
class="form-control"
placeholder="tci port"
id="tci_port"
aria-label="Device Port"
v-model="settings.remote.TCI.tci_port"
/>
</div>
</div>
</div>
</div>
<!-- RADIO CONTROL DISABLED -->
<div id="radio-control-disabled"></div>
<!-- RADIO CONTROL RIGCTLD -->
<div id="radio-control-rigctld"></div>
<!-- RADIO CONTROL TCI-->
<div id="radio-control-tci"></div>
<!-- RADIO CONTROL HELP -->
<div id="radio-control-help">
<!--
<strong>VOX:</strong> Use rig control mode 'none'
<br />
<strong>HAMLIB locally:</strong> configure in settings, then
@ -249,12 +224,12 @@ alert("not yet implemented")
<strong>HAMLIB remotely:</strong> Enter IP/Port, connection
happens automatically.
-->
</div>
</div>
</div>
<!--<div class="card-footer text-muted small" id="hamlib_info_field">
<!--<div class="card-footer text-muted small" id="hamlib_info_field">
Define Modem rig control mode (none/hamlib)
</div>
-->
</div>
</div>
</div>
</template>

View file

@ -2,13 +2,14 @@
import { Modal } from "bootstrap";
import { onMounted } from "vue";
import infoScreen_updater from "./infoScreen_updater.vue";
import settings_updater_core from "./settings_updater_core.vue";
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { sendModemCQ } from "../js/api.js";
import { useStateStore } from "../store/stateStore.js";
const state = useStateStore(pinia);
@ -50,6 +51,7 @@ function getRigControlStuff() {
case "disabled":
return true;
case "rigctld":
case "rigctld_bundle":
case "tci":
return state.radio_status;
default:
@ -61,7 +63,7 @@ function getRigControlStuff() {
}
function testHamlib() {
alert("Not yet implemented.");
sendModemCQ();
}
</script>
@ -284,69 +286,24 @@ function testHamlib() {
<option selected value="disabled">
Disabled (no rig control; use with VOX)
</option>
<option selected value="rigctld">Rigctld (Hamlib)</option>
<option selected value="rigctld">
Rigctld (external Hamlib)
</option>
<option selected value="rigctld_bundle">
Rigctld (internal Hamlib)
</option>
<option selected value="tci">TCI</option>
</select>
</div>
<div
:class="
settings.remote.RADIO.control == 'rigctld' ? '' : 'd-none'
settings.remote.RADIO.control == 'rigctld_bundle'
? ''
: 'd-none'
"
>
<!-- Shown when rigctld is selected-->
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-25"
>Rigctld control</label
>
<label class="input-group-text">
<button
type="button"
class="btn btn-sm btn-outline-success"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="false"
title="Start rigctld"
v-bind:class="{
disabled: state.rigctld_started == 'true',
}"
>
<i class="bi bi-play-fill"></i>
</button> </label
><label class="input-group-text">
<button
type="button"
class="btn btn-sm btn-outline-danger"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="false"
title="Stop rigctld"
v-bind:class="{
disabled:
state.rigctld_started == 'false' ||
state.rigctld_started === undefined,
}"
>
<i class="bi bi-stop-fill"></i>
</button>
</label>
<label class="input-group-text">
<button
type="button"
id="testHamlib"
class="btn btn-sm btn-outline-secondary"
data-bs-placement="bottom"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="true"
@click="testHamlib"
title="Test your hamlib settings and toggle PTT once. Button will become <strong class='text-success'>green</strong> on success and <strong class='text-danger'>red</strong> if fails."
>
PTT test
</button>
</label>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Radio port</span
@ -368,6 +325,26 @@ function testHamlib() {
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-25">Rigctld Test</label>
<label class="input-group-text">
<button
type="button"
id="testHamlib"
class="btn btn-sm btn-outline-secondary"
data-bs-placement="bottom"
data-bs-toggle="tooltip"
data-bs-trigger="hover"
data-bs-html="true"
@click="testHamlib"
title="Test your hamlib settings and toggle PTT once. Button will become <strong class='text-success'>green</strong> on success and <strong class='text-danger'>red</strong> if fails."
>
Send a CQ
</button>
</label>
</div>
</div>
<div
:class="
@ -450,7 +427,7 @@ function testHamlib() {
Modem version | {{ state.modem_version }}
</button>
<div :class="updateAvailable === '1' ? '' : 'd-none'">
<infoScreen_updater />
<settings_updater_core />
</div>
</div>
</div>

View file

@ -10,7 +10,7 @@ import { settingsStore as settings } from "../store/settingsStore.js";
</script>
<template>
<nav class="navbar bg-body-tertiary border-bottom">
<nav class="navbar bg-body-tertiary border-bottom z-0">
<div class="mx-auto">
<span class="badge bg-secondary me-4">
Modem Connection {{ state.modem_connection }}

View file

@ -1,4 +1,5 @@
<script setup lang="ts">
import settings_updater from "./settings_updater.vue";
import settings_station from "./settings_station.vue";
import settings_gui from "./settings_gui.vue";
import settings_chat from "./settings_chat.vue";
@ -22,6 +23,20 @@ import settings_exp from "./settings_exp.vue";
<li class="nav-item" role="presentation">
<button
class="nav-link active"
id="updater-tab"
data-bs-toggle="tab"
data-bs-target="#updater"
type="button"
role="tab"
aria-controls="home"
aria-selected="true"
>
Updater
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="station-tab"
data-bs-toggle="tab"
data-bs-target="#station"
@ -126,10 +141,23 @@ import settings_exp from "./settings_exp.vue";
>
<!-- SETTINGS Nav Tab panes -->
<!-- Station tab contents-->
<!-- Updater tab contents-->
<div class="tab-content">
<div
class="tab-pane active"
id="updater"
role="tabpanel"
aria-labelledby="updater-tab"
tabindex="0"
>
<settings_updater />
</div>
</div>
<!-- Station tab contents-->
<div class="tab-content">
<div
class="tab-pane"
id="station"
role="tabpanel"
aria-labelledby="station-tab"

View file

@ -5,9 +5,24 @@ import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { settingsStore as settings } from "../store/settingsStore.js";
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
</script>
<template>
<h5>...soon...</h5>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Enable message auto repeat</label>
<label class="input-group-text w-50">
<div class="form-check form-switch form-check-inline ms-2">
<input
class="form-check-input"
type="checkbox"
@change="onChange"
v-model="settings.remote.MESSAGES.enable_auto_repeat"
/>
<label class="form-check-label" for="enableMessagesAutoRepeatSwitch"
>Re-send message on beacon</label
>
</div>
</label>
</div>
</template>

View file

@ -32,495 +32,501 @@ import { serialDeviceOptions } from "../js/deviceFormHelper";
</div>
<hr class="m-2" />
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Radio model</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceid"
@change="onChange"
v-model.number="settings.remote.RADIO.model_id"
>
<option selected value="-- ignore --">-- ignore --</option>
<option value="1">Hamlib Dummy</option>
<option value="2">Hamlib NET rigctl</option>
<option value="4">FLRig FLRig</option>
<option value="5">TRXManager TRXManager 5.7.630+</option>
<option value="6">Hamlib Dummy No VFO</option>
<option value="29001">ADAT www.adat.ch (29001)</option>
<option value="25016">AE9RB Si570 (25016)</option>
<option value="25017">AE9RB Si570 (25017)</option>
<option value="17001">Alinco DX-77 (17001)</option>
<option value="17002">Alinco DX-SR8 (17002)</option>
<option value="25006">AmQRP DDS-60 (25006)</option>
<option value="25013">AMSAT-UK FUNcube (25013)</option>
<option value="25018">AMSAT-UK FUNcube (25018)</option>
<option value="5008">AOR AR2700 (5008)</option>
<option value="5006">AOR AR3000A (5006)</option>
<option value="5005">AOR AR3030 (5005)</option>
<option value="5004">AOR AR5000 (5004)</option>
<option value="5014">AOR AR5000A (5014)</option>
<option value="5003">AOR AR7030 (5003)</option>
<option value="5015">AOR AR7030 (5015)</option>
<option value="5002">AOR AR8000 (5002)</option>
<option value="5001">AOR AR8200 (5001)</option>
<option value="5013">AOR AR8600 (5013)</option>
<option value="5016">AOR SR2200 (5016)</option>
<option value="32001">Barrett 2050 (32001)</option>
<option value="32003">Barrett 4050 (32003)</option>
<option value="32002">Barrett 950 (32002)</option>
<option value="34001">CODAN Envoy (34001)</option>
<option value="34002">CODAN NGT (34002)</option>
<option value="25003">Coding Technologies (25003)</option>
<option value="31002">Dorji DRA818U (31002)</option>
<option value="31001">Dorji DRA818V (31001)</option>
<option value="9002">Drake R-8A (9002)</option>
<option value="9003">Drake R-8B (9003)</option>
<option value="23003">DTTS Microwave (23003)</option>
<option value="23004">DTTS Microwave (23004)</option>
<option value="33001">ELAD FDM-DUO (33001)</option>
<option value="2021">Elecraft K2 (2021)</option>
<option value="2029">Elecraft K3 (2029)</option>
<option value="2043">Elecraft K3S (2043)</option>
<option value="2047">Elecraft K4 (2047)</option>
<option value="2044">Elecraft KX2 (2044)</option>
<option value="2045">Elecraft KX3 (2045)</option>
<option value="2038">Elecraft XG3 (2038)</option>
<option value="25001">Elektor Elektor (25001)</option>
<option value="25007">Elektor Elektor (25007)</option>
<option value="25012">FiFi FiFi-SDR (25012)</option>
<option value="2036">FlexRadio 6xxx (2036)</option>
<option value="23001">Flex-radio SDR-1000 (23001)</option>
<option value="2048">FlexRadio/ANAN PowerSDR/Thetis (2048)</option>
<option value="25015">Funkamateur FA-SDR (25015)</option>
<option value="35001">GOMSPACE GS100 (35001)</option>
<option value="2046">Hilberling PT-8000A (2046)</option>
<option value="25019">HobbyPCB RS-HFIQ (25019)</option>
<option value="3054">Icom IC (3054)</option>
<option value="3002">Icom IC-1275 (3002)</option>
<option value="3003">Icom IC-271 (3003)</option>
<option value="3072">Icom IC-2730 (3072)</option>
<option value="3004">Icom IC-275 (3004)</option>
<option value="3005">Icom IC-375 (3005)</option>
<option value="3006">Icom IC-471 (3006)</option>
<option value="3007">Icom IC-475 (3007)</option>
<option value="3008">Icom IC-575 (3008)</option>
<option value="3060">Icom IC-7000 (3060)</option>
<option value="3055">Icom IC-703 (3055)</option>
<option value="3085">Icom IC-705 (3085)</option>
<option value="3009">Icom IC-706 (3009)</option>
<option value="3010">Icom IC-706MkII (3010)</option>
<option value="3011">Icom IC-706MkIIG (3011)</option>
<option value="3012">Icom IC-707 (3012)</option>
<option value="3070">Icom IC-7100 (3070)</option>
<option value="3013">Icom IC-718 (3013)</option>
<option value="3061">Icom IC-7200 (3061)</option>
<option value="3014">Icom IC-725 (3014)</option>
<option value="3015">Icom IC-726 (3015)</option>
<option value="3016">Icom IC-728 (3016)</option>
<option value="3017">Icom IC-729 (3017)</option>
<option value="3073">Icom IC-7300 (3073)</option>
<option value="3019">Icom IC-735 (3019)</option>
<option value="3020">Icom IC-736 (3020)</option>
<option value="3021">Icom IC-737 (3021)</option>
<option value="3022">Icom IC-738 (3022)</option>
<option value="3067">Icom IC-7410 (3067)</option>
<option value="3023">Icom IC-746 (3023)</option>
<option value="3046">Icom IC-746PRO (3046)</option>
<option value="3024">Icom IC-751 (3024)</option>
<option value="3026">Icom IC-756 (3026)</option>
<option value="3027">Icom IC-756PRO (3027)</option>
<option value="3047">Icom IC-756PROII (3047)</option>
<option value="3057">Icom IC-756PROIII (3057)</option>
<option value="3063">Icom IC-7600 (3063)</option>
<option value="3028">Icom IC-761 (3028)</option>
<option value="3078">Icom IC-7610 (3078)</option>
<option value="3029">Icom IC-765 (3029)</option>
<option value="3062">Icom IC-7700 (3062)</option>
<option value="3030">Icom IC-775 (3030)</option>
<option value="3045">Icom IC-78 (3045)</option>
<option value="3056">Icom IC-7800 (3056)</option>
<option value="3031">Icom IC-781 (3031)</option>
<option value="3075">Icom IC-7850/7851 (3075)</option>
<option value="3032">Icom IC-820H (3032)</option>
<option value="3034">Icom IC-821H (3034)</option>
<option value="3044">Icom IC-910 (3044)</option>
<option value="3068">Icom IC-9100 (3068)</option>
<option value="3065">Icom IC-92D (3065)</option>
<option value="3035">Icom IC-970 (3035)</option>
<option value="3081">Icom IC-9700 (3081)</option>
<option value="3086">Icom IC-F8101 (3086)</option>
<option value="30001">Icom IC-M700PRO (30001)</option>
<option value="30003">Icom IC-M710 (30003)</option>
<option value="30002">Icom IC-M802 (30002)</option>
<option value="30004">Icom IC-M803 (30004)</option>
<option value="4002">Icom IC-PCR100 (4002)</option>
<option value="4001">Icom IC-PCR1000 (4001)</option>
<option value="4003">Icom IC-PCR1500 (4003)</option>
<option value="4004">Icom IC-PCR2500 (4004)</option>
<option value="3036">Icom IC-R10 (3036)</option>
<option value="3058">Icom IC-R20 (3058)</option>
<option value="3080">Icom IC-R30 (3080)</option>
<option value="3077">Icom IC-R6 (3077)</option>
<option value="3040">Icom IC-R7000 (3040)</option>
<option value="3037">Icom IC-R71 (3037)</option>
<option value="3041">Icom IC-R7100 (3041)</option>
<option value="3038">Icom IC-R72 (3038)</option>
<option value="3039">Icom IC-R75 (3039)</option>
<option value="3042">Icom ICR-8500 (3042)</option>
<option value="3079">Icom IC-R8600 (3079)</option>
<option value="3043">Icom IC-R9000 (3043)</option>
<option value="3066">Icom IC-R9500 (3066)</option>
<option value="3069">Icom IC-RX7 (3069)</option>
<option value="3083">Icom ID-31 (3083)</option>
<option value="3082">Icom ID-4100 (3082)</option>
<option value="3084">Icom ID-51 (3084)</option>
<option value="3071">Icom ID-5100 (3071)</option>
<option value="6001">JRC JST-145 (6001)</option>
<option value="6002">JRC JST-245 (6002)</option>
<option value="6005">JRC NRD-525 (6005)</option>
<option value="6006">JRC NRD-535D (6006)</option>
<option value="6007">JRC NRD-545 (6007)</option>
<option value="18001">Kachina 505DSP (18001)</option>
<option value="2015">Kenwood R-5000 (2015)</option>
<option value="2033">Kenwood TH-D72A (2033)</option>
<option value="2042">Kenwood TH-D74 (2042)</option>
<option value="2017">Kenwood TH-D7A (2017)</option>
<option value="2019">Kenwood TH-F6A (2019)</option>
<option value="2020">Kenwood TH-F7E (2020)</option>
<option value="2023">Kenwood TH-G71 (2023)</option>
<option value="2026">Kenwood TM-D700 (2026)</option>
<option value="2034">Kenwood TM-D710(G) (2034)</option>
<option value="2027">Kenwood TM-V7 (2027)</option>
<option value="2035">Kenwood TM-V71(A) (2035)</option>
<option value="2030">Kenwood TRC-80 (2030)</option>
<option value="2025">Kenwood TS-140S (2025)</option>
<option value="2014">Kenwood TS-2000 (2014)</option>
<option value="2002">Kenwood TS-440S (2002)</option>
<option value="2003">Kenwood TS-450S (2003)</option>
<option value="2028">Kenwood TS-480 (2028)</option>
<option value="2001">Kenwood TS-50S (2001)</option>
<option value="2004">Kenwood TS-570D (2004)</option>
<option value="2016">Kenwood TS-570S (2016)</option>
<option value="2031">Kenwood TS-590S (2031)</option>
<option value="2037">Kenwood TS-590SG (2037)</option>
<option value="2024">Kenwood TS-680S (2024)</option>
<option value="2005">Kenwood TS-690S (2005)</option>
<option value="2006">Kenwood TS-711 (2006)</option>
<option value="2007">Kenwood TS-790 (2007)</option>
<option value="2008">Kenwood TS-811 (2008)</option>
<option value="2009">Kenwood TS-850 (2009)</option>
<option value="2010">Kenwood TS-870S (2010)</option>
<option value="2041">Kenwood TS-890S (2041)</option>
<option value="2022">Kenwood TS-930 (2022)</option>
<option value="2011">Kenwood TS-940S (2011)</option>
<option value="2012">Kenwood TS-950S (2012)</option>
<option value="2013">Kenwood TS-950SDX (2013)</option>
<option value="2039">Kenwood TS-990S (2039)</option>
<option value="25011">KTH-SDR kit (25011)</option>
<option value="2050">Lab599 TX-500 (2050)</option>
<option value="10004">Lowe HF-235 (10004)</option>
<option value="1045">M0NKA mcHF (1045)</option>
<option value="2049">Malachite DSP (2049)</option>
<option value="3074">Microtelecom Perseus (3074)</option>
<option value="25008">mRS miniVNA (25008)</option>
<option value="25014">N2ADR HiQSDR (25014)</option>
<option value="2040">OpenHPSDR PiHPSDR (2040)</option>
<option value="3053">Optoelectronics OptoScan456 (3053)</option>
<option value="3052">Optoelectronics OptoScan535 (3052)</option>
<option value="28001">Philips/Simoco PRM8060 (28001)</option>
<option value="11005">Racal RA3702 (11005)</option>
<option value="11003">Racal RA6790/GM (11003)</option>
<option value="8004">Radio Shack (8004)</option>
<option value="24001">RFT EKD-500 (24001)</option>
<option value="27002">Rohde&Schwarz EB200 (27002)</option>
<option value="27004">Rohde&Schwarz EK895/6 (27004)</option>
<option value="27001">Rohde&Schwarz ESMC (27001)</option>
<option value="27003">Rohde&Schwarz XK2100 (27003)</option>
<option value="25002">SAT-Schneider DRT1 (25002)</option>
<option value="2051">SDRPlay SDRUno (2051)</option>
<option value="2032">SigFox Transfox (2032)</option>
<option value="14004">Skanti TRP (14004)</option>
<option value="14002">Skanti TRP8000 (14002)</option>
<option value="25009">SoftRock Si570 (25009)</option>
<option value="22001">TAPR DSP-10 (22001)</option>
<option value="3064">Ten-Tec Delta (3064)</option>
<option value="3051">Ten-Tec Omni (3051)</option>
<option value="16003">Ten-Tec RX-320 (16003)</option>
<option value="16012">Ten-Tec RX-331 (16012)</option>
<option value="16004">Ten-Tec RX-340 (16004)</option>
<option value="16005">Ten-Tec RX-350 (16005)</option>
<option value="16007">Ten-Tec TT-516 (16007)</option>
<option value="16002">Ten-Tec TT-538 (16002)</option>
<option value="16001">Ten-Tec TT-550 (16001)</option>
<option value="16008">Ten-Tec TT-565 (16008)</option>
<option value="16009">Ten-Tec TT-585 (16009)</option>
<option value="16011">Ten-Tec TT-588 (16011)</option>
<option value="16013">Ten-Tec TT-599 (16013)</option>
<option value="8002">Uniden BC245xlt (8002)</option>
<option value="8006">Uniden BC250D (8006)</option>
<option value="8001">Uniden BC780xlt (8001)</option>
<option value="8003">Uniden BC895xlt (8003)</option>
<option value="8012">Uniden BC898T (8012)</option>
<option value="8010">Uniden BCD-396T (8010)</option>
<option value="8011">Uniden BCD-996T (8011)</option>
<option value="1033">Vertex Standard (1033)</option>
<option value="26001">Video4Linux SW/FM (26001)</option>
<option value="26002">Video4Linux2 SW/FM (26002)</option>
<option value="12004">Watkins-Johnson WJ-8888 (12004)</option>
<option value="15001">Winradio WR-1000 (15001)</option>
<option value="15002">Winradio WR-1500 (15002)</option>
<option value="15003">Winradio WR-1550 (15003)</option>
<option value="15004">Winradio WR-3100 (15004)</option>
<option value="15005">Winradio WR-3150 (15005)</option>
<option value="15006">Winradio WR-3500 (15006)</option>
<option value="15007">Winradio WR-3700 (15007)</option>
<option value="15009">Winradio WR-G313 (15009)</option>
<option value="3088">Xiegu G90 (3088)</option>
<option value="3076">Xiegu X108G (3076)</option>
<option value="3089">Xiegu X5105 (3089)</option>
<option value="3087">Xiegu X6100 (3087)</option>
<option value="1017">Yaesu FRG-100 (1017)</option>
<option value="1019">Yaesu FRG-8800 (1019)</option>
<option value="1018">Yaesu FRG-9600 (1018)</option>
<option value="1021">Yaesu FT-100 (1021)</option>
<option value="1003">Yaesu FT-1000D (1003)</option>
<option value="1024">Yaesu FT-1000MP (1024)</option>
<option value="1029">Yaesu FT-2000 (1029)</option>
<option value="1027">Yaesu FT-450 (1027)</option>
<option value="1046">Yaesu FT-450D (1046)</option>
<option value="1039">Yaesu FT-600 (1039)</option>
<option value="1047">Yaesu FT-650 (1047)</option>
<option value="1049">Yaesu FT-710 (1049)</option>
<option value="1010">Yaesu FT-736R (1010)</option>
<option value="1005">Yaesu FT-747GX (1005)</option>
<option value="1006">Yaesu FT-757GX (1006)</option>
<option value="1007">Yaesu FT-757GXII (1007)</option>
<option value="1009">Yaesu FT-767GX (1009)</option>
<option value="1020">Yaesu FT-817 (1020)</option>
<option value="1041">Yaesu FT-818 (1041)</option>
<option value="1011">Yaesu FT-840 (1011)</option>
<option value="1001">Yaesu FT-847 (1001)</option>
<option value="1038">Yaesu FT-847UNI (1038)</option>
<option value="1022">Yaesu FT-857 (1022)</option>
<option value="1015">Yaesu FT-890 (1015)</option>
<option value="1036">Yaesu FT-891 (1036)</option>
<option value="1023">Yaesu FT-897 (1023)</option>
<option value="1043">Yaesu FT-897D (1043)</option>
<option value="1013">Yaesu FT-900 (1013)</option>
<option value="1014">Yaesu FT-920 (1014)</option>
<option value="1028">Yaesu FT-950 (1028)</option>
<option value="1031">Yaesu FT-980 (1031)</option>
<option value="1016">Yaesu FT-990 (1016)</option>
<option value="1048">Yaesu FT-990 (1048)</option>
<option value="1035">Yaesu FT-991 (1035)</option>
<option value="1042">Yaesu FTDX-10 (1042)</option>
<option value="1040">Yaesu FTDX-101D (1040)</option>
<option value="1044">Yaesu FTDX-101MP (1044)</option>
<option value="1034">Yaesu FTDX-1200 (1034)</option>
<option value="1037">Yaesu FTDX-3000 (1037)</option>
<option value="1032">Yaesu FTDX-5000 (1032)</option>
<option value="1030">Yaesu FTDX-9000 (1030)</option>
<option value="1004">Yaesu MARK-V (1004)</option>
<option value="1025">Yaesu MARK-V (1025)</option>
<option value="1026">Yaesu VR-5000 (1026)</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Radio port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceport"
style="width: 7rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
<div
:class="settings.remote.RADIO.control == 'rigctld_bundle' ? '' : 'd-none'"
>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Radio model</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceid"
@change="onChange"
v-model.number="settings.remote.RADIO.model_id"
>
{{ option.description }}
</option>
</select>
</div>
<option selected value="-- ignore --">-- ignore --</option>
<option value="1">Hamlib Dummy</option>
<option value="2">Hamlib NET rigctl</option>
<option value="4">FLRig FLRig</option>
<option value="5">TRXManager TRXManager 5.7.630+</option>
<option value="6">Hamlib Dummy No VFO</option>
<option value="29001">ADAT www.adat.ch (29001)</option>
<option value="25016">AE9RB Si570 (25016)</option>
<option value="25017">AE9RB Si570 (25017)</option>
<option value="17001">Alinco DX-77 (17001)</option>
<option value="17002">Alinco DX-SR8 (17002)</option>
<option value="25006">AmQRP DDS-60 (25006)</option>
<option value="25013">AMSAT-UK FUNcube (25013)</option>
<option value="25018">AMSAT-UK FUNcube (25018)</option>
<option value="5008">AOR AR2700 (5008)</option>
<option value="5006">AOR AR3000A (5006)</option>
<option value="5005">AOR AR3030 (5005)</option>
<option value="5004">AOR AR5000 (5004)</option>
<option value="5014">AOR AR5000A (5014)</option>
<option value="5003">AOR AR7030 (5003)</option>
<option value="5015">AOR AR7030 (5015)</option>
<option value="5002">AOR AR8000 (5002)</option>
<option value="5001">AOR AR8200 (5001)</option>
<option value="5013">AOR AR8600 (5013)</option>
<option value="5016">AOR SR2200 (5016)</option>
<option value="32001">Barrett 2050 (32001)</option>
<option value="32003">Barrett 4050 (32003)</option>
<option value="32002">Barrett 950 (32002)</option>
<option value="34001">CODAN Envoy (34001)</option>
<option value="34002">CODAN NGT (34002)</option>
<option value="25003">Coding Technologies (25003)</option>
<option value="31002">Dorji DRA818U (31002)</option>
<option value="31001">Dorji DRA818V (31001)</option>
<option value="9002">Drake R-8A (9002)</option>
<option value="9003">Drake R-8B (9003)</option>
<option value="23003">DTTS Microwave (23003)</option>
<option value="23004">DTTS Microwave (23004)</option>
<option value="33001">ELAD FDM-DUO (33001)</option>
<option value="2021">Elecraft K2 (2021)</option>
<option value="2029">Elecraft K3 (2029)</option>
<option value="2043">Elecraft K3S (2043)</option>
<option value="2047">Elecraft K4 (2047)</option>
<option value="2044">Elecraft KX2 (2044)</option>
<option value="2045">Elecraft KX3 (2045)</option>
<option value="2038">Elecraft XG3 (2038)</option>
<option value="25001">Elektor Elektor (25001)</option>
<option value="25007">Elektor Elektor (25007)</option>
<option value="25012">FiFi FiFi-SDR (25012)</option>
<option value="2036">FlexRadio 6xxx (2036)</option>
<option value="23001">Flex-radio SDR-1000 (23001)</option>
<option value="2048">FlexRadio/ANAN PowerSDR/Thetis (2048)</option>
<option value="25015">Funkamateur FA-SDR (25015)</option>
<option value="35001">GOMSPACE GS100 (35001)</option>
<option value="2046">Hilberling PT-8000A (2046)</option>
<option value="25019">HobbyPCB RS-HFIQ (25019)</option>
<option value="3054">Icom IC (3054)</option>
<option value="3002">Icom IC-1275 (3002)</option>
<option value="3003">Icom IC-271 (3003)</option>
<option value="3072">Icom IC-2730 (3072)</option>
<option value="3004">Icom IC-275 (3004)</option>
<option value="3005">Icom IC-375 (3005)</option>
<option value="3006">Icom IC-471 (3006)</option>
<option value="3007">Icom IC-475 (3007)</option>
<option value="3008">Icom IC-575 (3008)</option>
<option value="3060">Icom IC-7000 (3060)</option>
<option value="3055">Icom IC-703 (3055)</option>
<option value="3085">Icom IC-705 (3085)</option>
<option value="3009">Icom IC-706 (3009)</option>
<option value="3010">Icom IC-706MkII (3010)</option>
<option value="3011">Icom IC-706MkIIG (3011)</option>
<option value="3012">Icom IC-707 (3012)</option>
<option value="3070">Icom IC-7100 (3070)</option>
<option value="3013">Icom IC-718 (3013)</option>
<option value="3061">Icom IC-7200 (3061)</option>
<option value="3014">Icom IC-725 (3014)</option>
<option value="3015">Icom IC-726 (3015)</option>
<option value="3016">Icom IC-728 (3016)</option>
<option value="3017">Icom IC-729 (3017)</option>
<option value="3073">Icom IC-7300 (3073)</option>
<option value="3019">Icom IC-735 (3019)</option>
<option value="3020">Icom IC-736 (3020)</option>
<option value="3021">Icom IC-737 (3021)</option>
<option value="3022">Icom IC-738 (3022)</option>
<option value="3067">Icom IC-7410 (3067)</option>
<option value="3023">Icom IC-746 (3023)</option>
<option value="3046">Icom IC-746PRO (3046)</option>
<option value="3024">Icom IC-751 (3024)</option>
<option value="3026">Icom IC-756 (3026)</option>
<option value="3027">Icom IC-756PRO (3027)</option>
<option value="3047">Icom IC-756PROII (3047)</option>
<option value="3057">Icom IC-756PROIII (3057)</option>
<option value="3063">Icom IC-7600 (3063)</option>
<option value="3028">Icom IC-761 (3028)</option>
<option value="3078">Icom IC-7610 (3078)</option>
<option value="3029">Icom IC-765 (3029)</option>
<option value="3062">Icom IC-7700 (3062)</option>
<option value="3030">Icom IC-775 (3030)</option>
<option value="3045">Icom IC-78 (3045)</option>
<option value="3056">Icom IC-7800 (3056)</option>
<option value="3031">Icom IC-781 (3031)</option>
<option value="3075">Icom IC-7850/7851 (3075)</option>
<option value="3032">Icom IC-820H (3032)</option>
<option value="3034">Icom IC-821H (3034)</option>
<option value="3044">Icom IC-910 (3044)</option>
<option value="3068">Icom IC-9100 (3068)</option>
<option value="3065">Icom IC-92D (3065)</option>
<option value="3035">Icom IC-970 (3035)</option>
<option value="3081">Icom IC-9700 (3081)</option>
<option value="3086">Icom IC-F8101 (3086)</option>
<option value="30001">Icom IC-M700PRO (30001)</option>
<option value="30003">Icom IC-M710 (30003)</option>
<option value="30002">Icom IC-M802 (30002)</option>
<option value="30004">Icom IC-M803 (30004)</option>
<option value="4002">Icom IC-PCR100 (4002)</option>
<option value="4001">Icom IC-PCR1000 (4001)</option>
<option value="4003">Icom IC-PCR1500 (4003)</option>
<option value="4004">Icom IC-PCR2500 (4004)</option>
<option value="3036">Icom IC-R10 (3036)</option>
<option value="3058">Icom IC-R20 (3058)</option>
<option value="3080">Icom IC-R30 (3080)</option>
<option value="3077">Icom IC-R6 (3077)</option>
<option value="3040">Icom IC-R7000 (3040)</option>
<option value="3037">Icom IC-R71 (3037)</option>
<option value="3041">Icom IC-R7100 (3041)</option>
<option value="3038">Icom IC-R72 (3038)</option>
<option value="3039">Icom IC-R75 (3039)</option>
<option value="3042">Icom ICR-8500 (3042)</option>
<option value="3079">Icom IC-R8600 (3079)</option>
<option value="3043">Icom IC-R9000 (3043)</option>
<option value="3066">Icom IC-R9500 (3066)</option>
<option value="3069">Icom IC-RX7 (3069)</option>
<option value="3083">Icom ID-31 (3083)</option>
<option value="3082">Icom ID-4100 (3082)</option>
<option value="3084">Icom ID-51 (3084)</option>
<option value="3071">Icom ID-5100 (3071)</option>
<option value="6001">JRC JST-145 (6001)</option>
<option value="6002">JRC JST-245 (6002)</option>
<option value="6005">JRC NRD-525 (6005)</option>
<option value="6006">JRC NRD-535D (6006)</option>
<option value="6007">JRC NRD-545 (6007)</option>
<option value="18001">Kachina 505DSP (18001)</option>
<option value="2015">Kenwood R-5000 (2015)</option>
<option value="2033">Kenwood TH-D72A (2033)</option>
<option value="2042">Kenwood TH-D74 (2042)</option>
<option value="2017">Kenwood TH-D7A (2017)</option>
<option value="2019">Kenwood TH-F6A (2019)</option>
<option value="2020">Kenwood TH-F7E (2020)</option>
<option value="2023">Kenwood TH-G71 (2023)</option>
<option value="2026">Kenwood TM-D700 (2026)</option>
<option value="2034">Kenwood TM-D710(G) (2034)</option>
<option value="2027">Kenwood TM-V7 (2027)</option>
<option value="2035">Kenwood TM-V71(A) (2035)</option>
<option value="2030">Kenwood TRC-80 (2030)</option>
<option value="2025">Kenwood TS-140S (2025)</option>
<option value="2014">Kenwood TS-2000 (2014)</option>
<option value="2002">Kenwood TS-440S (2002)</option>
<option value="2003">Kenwood TS-450S (2003)</option>
<option value="2028">Kenwood TS-480 (2028)</option>
<option value="2001">Kenwood TS-50S (2001)</option>
<option value="2004">Kenwood TS-570D (2004)</option>
<option value="2016">Kenwood TS-570S (2016)</option>
<option value="2031">Kenwood TS-590S (2031)</option>
<option value="2037">Kenwood TS-590SG (2037)</option>
<option value="2024">Kenwood TS-680S (2024)</option>
<option value="2005">Kenwood TS-690S (2005)</option>
<option value="2006">Kenwood TS-711 (2006)</option>
<option value="2007">Kenwood TS-790 (2007)</option>
<option value="2008">Kenwood TS-811 (2008)</option>
<option value="2009">Kenwood TS-850 (2009)</option>
<option value="2010">Kenwood TS-870S (2010)</option>
<option value="2041">Kenwood TS-890S (2041)</option>
<option value="2022">Kenwood TS-930 (2022)</option>
<option value="2011">Kenwood TS-940S (2011)</option>
<option value="2012">Kenwood TS-950S (2012)</option>
<option value="2013">Kenwood TS-950SDX (2013)</option>
<option value="2039">Kenwood TS-990S (2039)</option>
<option value="25011">KTH-SDR kit (25011)</option>
<option value="2050">Lab599 TX-500 (2050)</option>
<option value="10004">Lowe HF-235 (10004)</option>
<option value="1045">M0NKA mcHF (1045)</option>
<option value="2049">Malachite DSP (2049)</option>
<option value="3074">Microtelecom Perseus (3074)</option>
<option value="25008">mRS miniVNA (25008)</option>
<option value="25014">N2ADR HiQSDR (25014)</option>
<option value="2040">OpenHPSDR PiHPSDR (2040)</option>
<option value="3053">Optoelectronics OptoScan456 (3053)</option>
<option value="3052">Optoelectronics OptoScan535 (3052)</option>
<option value="28001">Philips/Simoco PRM8060 (28001)</option>
<option value="11005">Racal RA3702 (11005)</option>
<option value="11003">Racal RA6790/GM (11003)</option>
<option value="8004">Radio Shack (8004)</option>
<option value="24001">RFT EKD-500 (24001)</option>
<option value="27002">Rohde&Schwarz EB200 (27002)</option>
<option value="27004">Rohde&Schwarz EK895/6 (27004)</option>
<option value="27001">Rohde&Schwarz ESMC (27001)</option>
<option value="27003">Rohde&Schwarz XK2100 (27003)</option>
<option value="25002">SAT-Schneider DRT1 (25002)</option>
<option value="2051">SDRPlay SDRUno (2051)</option>
<option value="2032">SigFox Transfox (2032)</option>
<option value="14004">Skanti TRP (14004)</option>
<option value="14002">Skanti TRP8000 (14002)</option>
<option value="25009">SoftRock Si570 (25009)</option>
<option value="22001">TAPR DSP-10 (22001)</option>
<option value="3064">Ten-Tec Delta (3064)</option>
<option value="3051">Ten-Tec Omni (3051)</option>
<option value="16003">Ten-Tec RX-320 (16003)</option>
<option value="16012">Ten-Tec RX-331 (16012)</option>
<option value="16004">Ten-Tec RX-340 (16004)</option>
<option value="16005">Ten-Tec RX-350 (16005)</option>
<option value="16007">Ten-Tec TT-516 (16007)</option>
<option value="16002">Ten-Tec TT-538 (16002)</option>
<option value="16001">Ten-Tec TT-550 (16001)</option>
<option value="16008">Ten-Tec TT-565 (16008)</option>
<option value="16009">Ten-Tec TT-585 (16009)</option>
<option value="16011">Ten-Tec TT-588 (16011)</option>
<option value="16013">Ten-Tec TT-599 (16013)</option>
<option value="8002">Uniden BC245xlt (8002)</option>
<option value="8006">Uniden BC250D (8006)</option>
<option value="8001">Uniden BC780xlt (8001)</option>
<option value="8003">Uniden BC895xlt (8003)</option>
<option value="8012">Uniden BC898T (8012)</option>
<option value="8010">Uniden BCD-396T (8010)</option>
<option value="8011">Uniden BCD-996T (8011)</option>
<option value="1033">Vertex Standard (1033)</option>
<option value="26001">Video4Linux SW/FM (26001)</option>
<option value="26002">Video4Linux2 SW/FM (26002)</option>
<option value="12004">Watkins-Johnson WJ-8888 (12004)</option>
<option value="15001">Winradio WR-1000 (15001)</option>
<option value="15002">Winradio WR-1500 (15002)</option>
<option value="15003">Winradio WR-1550 (15003)</option>
<option value="15004">Winradio WR-3100 (15004)</option>
<option value="15005">Winradio WR-3150 (15005)</option>
<option value="15006">Winradio WR-3500 (15006)</option>
<option value="15007">Winradio WR-3700 (15007)</option>
<option value="15009">Winradio WR-G313 (15009)</option>
<option value="3088">Xiegu G90 (3088)</option>
<option value="3076">Xiegu X108G (3076)</option>
<option value="3089">Xiegu X5105 (3089)</option>
<option value="3087">Xiegu X6100 (3087)</option>
<option value="1017">Yaesu FRG-100 (1017)</option>
<option value="1019">Yaesu FRG-8800 (1019)</option>
<option value="1018">Yaesu FRG-9600 (1018)</option>
<option value="1021">Yaesu FT-100 (1021)</option>
<option value="1003">Yaesu FT-1000D (1003)</option>
<option value="1024">Yaesu FT-1000MP (1024)</option>
<option value="1029">Yaesu FT-2000 (1029)</option>
<option value="1027">Yaesu FT-450 (1027)</option>
<option value="1046">Yaesu FT-450D (1046)</option>
<option value="1039">Yaesu FT-600 (1039)</option>
<option value="1047">Yaesu FT-650 (1047)</option>
<option value="1049">Yaesu FT-710 (1049)</option>
<option value="1010">Yaesu FT-736R (1010)</option>
<option value="1005">Yaesu FT-747GX (1005)</option>
<option value="1006">Yaesu FT-757GX (1006)</option>
<option value="1007">Yaesu FT-757GXII (1007)</option>
<option value="1009">Yaesu FT-767GX (1009)</option>
<option value="1020">Yaesu FT-817 (1020)</option>
<option value="1041">Yaesu FT-818 (1041)</option>
<option value="1011">Yaesu FT-840 (1011)</option>
<option value="1001">Yaesu FT-847 (1001)</option>
<option value="1038">Yaesu FT-847UNI (1038)</option>
<option value="1022">Yaesu FT-857 (1022)</option>
<option value="1015">Yaesu FT-890 (1015)</option>
<option value="1036">Yaesu FT-891 (1036)</option>
<option value="1023">Yaesu FT-897 (1023)</option>
<option value="1043">Yaesu FT-897D (1043)</option>
<option value="1013">Yaesu FT-900 (1013)</option>
<option value="1014">Yaesu FT-920 (1014)</option>
<option value="1028">Yaesu FT-950 (1028)</option>
<option value="1031">Yaesu FT-980 (1031)</option>
<option value="1016">Yaesu FT-990 (1016)</option>
<option value="1048">Yaesu FT-990 (1048)</option>
<option value="1035">Yaesu FT-991 (1035)</option>
<option value="1042">Yaesu FTDX-10 (1042)</option>
<option value="1040">Yaesu FTDX-101D (1040)</option>
<option value="1044">Yaesu FTDX-101MP (1044)</option>
<option value="1034">Yaesu FTDX-1200 (1034)</option>
<option value="1037">Yaesu FTDX-3000 (1037)</option>
<option value="1032">Yaesu FTDX-5000 (1032)</option>
<option value="1030">Yaesu FTDX-9000 (1030)</option>
<option value="1004">Yaesu MARK-V (1004)</option>
<option value="1025">Yaesu MARK-V (1025)</option>
<option value="1026">Yaesu VR-5000 (1026)</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Serial speed</span>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Radio port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_serialspeed"
@change="onChange"
v-model.number="settings.remote.RADIO.serial_speed"
>
<option selected value="ignore">-- ignore --</option>
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option value="9600">9600</option>
<option value="14400">14400</option>
<option value="19200">19200</option>
<option value="28800">28800</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Data bits</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_data_bits"
@change="onChange"
v-model.number="settings.remote.RADIO.data_bits"
>
<option selected value="ignore">-- ignore --</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Stop bits</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_stop_bits"
@change="onChange"
v-model.number="settings.remote.RADIO.stop_bits"
>
<option selected value="ignore">-- ignore --</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Serial handshake</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_handshake"
@change="onChange"
v-model="settings.remote.RADIO.serial_handshake"
>
<option selected value="ignore">-- ignore --</option>
<option value="None">None (Default)</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT device port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_ptt_port"
@change="onChange"
v-model="settings.remote.RADIO.ptt_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_deviceport"
style="width: 7rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_port"
>
{{ option.description }}
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT type</span>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
>
{{ option.description }}
</option>
</select>
</div>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_pttprotocol"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.ptt_type"
>
<option selected value="ignore">-- ignore --</option>
<option value="NONE">NONE</option>
<option value="RIG">RIG</option>
<option value="USB">USB</option>
<option value="RTS">Serial RTS</option>
<option value="PARALLEL">Rig PARALLEL</option>
<option value="MICDATA">Rig MICDATA</option>
<option value="CM108">Rig CM108</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">DCD</span>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Serial speed</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_dcd"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_dcd"
>
<option selected value="ignore">-- ignore --</option>
<option value="NONE">NONE</option>
<option value="RIG">RIG/CAT</option>
<option value="DSR">DSR</option>
<option value="CTS">CTS</option>
<option value="CD">CD</option>
<option value="PARALLEL">PARALLEL</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">DTR</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_serialspeed"
@change="onChange"
v-model.number="settings.remote.RADIO.serial_speed"
>
<option selected value="0">-- ignore --</option>
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option value="9600">9600</option>
<option value="14400">14400</option>
<option value="19200">19200</option>
<option value="28800">28800</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Data bits</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_dtrstate"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_dtr"
>
<option selected value="ignore">-- ignore --</option>
<option value="OFF">OFF</option>
<option value="ON">ON</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Rigctld command</span>
<input
type="text"
class="form-control"
id="hamlib_rigctld_command"
aria-label="Device Port"
aria-describedby="basic-addon1"
disabled
placeholder="auto populated from above settings"
/>
<button
class="btn btn-outline-secondary"
type="button"
id="btnHamlibCopyCommand"
>
<i id="btnHamlibCopyCommandBi" class="bi bi-clipboard"></i>
</button>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Rigctld custom arguments</span
>
<input
type="text"
class="form-control"
placeholder="not typically needed"
id="hamlib_rigctld_custom_args"
aria-label="Custom arguments"
aria-describedby="basic-addon1"
@change="onChange"
v-model="settings.remote.RIGCTLD.arguments"
/>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_data_bits"
@change="onChange"
v-model.number="settings.remote.RADIO.data_bits"
>
<option selected value="0">-- ignore --</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Stop bits</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_stop_bits"
@change="onChange"
v-model.number="settings.remote.RADIO.stop_bits"
>
<option selected value="0">-- ignore --</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Serial handshake</span
>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_handshake"
@change="onChange"
v-model="settings.remote.RADIO.serial_handshake"
>
<option selected value="ignore">-- ignore --</option>
<option value="None">None (Default)</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT device port</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_ptt_port"
@change="onChange"
v-model="settings.remote.RADIO.ptt_port"
>
<option
v-for="option in serialDeviceOptions()"
v-bind:value="option.port"
>
{{ option.description }}
</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">PTT type</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_pttprotocol"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.ptt_type"
>
<option selected value="ignore">-- ignore --</option>
<option value="NONE">NONE</option>
<option value="RIG">RIG</option>
<option value="USB">USB</option>
<option value="RTS">Serial RTS</option>
<option value="PARALLEL">Rig PARALLEL</option>
<option value="MICDATA">Rig MICDATA</option>
<option value="CM108">Rig CM108</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">DCD</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_dcd"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_dcd"
>
<option selected value="ignore">-- ignore --</option>
<option value="NONE">NONE</option>
<option value="RIG">RIG/CAT</option>
<option value="DSR">DSR</option>
<option value="CTS">CTS</option>
<option value="CD">CD</option>
<option value="PARALLEL">PARALLEL</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">DTR</span>
<select
class="form-select form-select-sm"
aria-label=".form-select-sm"
id="hamlib_dtrstate"
style="width: 0.5rem"
@change="onChange"
v-model="settings.remote.RADIO.serial_dtr"
>
<option selected value="ignore">-- ignore --</option>
<option value="OFF">OFF</option>
<option value="ON">ON</option>
</select>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px">Rigctld command</span>
<input
type="text"
class="form-control"
id="hamlib_rigctld_command"
aria-label="Device Port"
aria-describedby="basic-addon1"
disabled
placeholder="auto populated from above settings"
/>
<button
class="btn btn-outline-secondary"
type="button"
id="btnHamlibCopyCommand"
>
<i id="btnHamlibCopyCommandBi" class="bi bi-clipboard"></i>
</button>
</div>
<div class="input-group input-group-sm mb-1">
<span class="input-group-text" style="width: 180px"
>Rigctld custom arguments</span
>
<input
type="text"
class="form-control"
placeholder="not typically needed"
id="hamlib_rigctld_custom_args"
aria-label="Custom arguments"
aria-describedby="basic-addon1"
@change="onChange"
v-model="settings.remote.RIGCTLD.arguments"
/>
</div>
</div>
</template>

View file

@ -18,7 +18,8 @@ import settings_tci from "./settings_tci.vue";
<option selected value="disabled">
Disabled / VOX (no rig control - use with VOX)
</option>
<option selected value="rigctld">Rigctld (Hamlib)</option>
<option selected value="rigctld">Rigctld (external Hamlib)</option>
<option selected value="rigctld_bundle">Rigctld (internal Hamlib)</option>
<option selected value="tci">TCI</option>
</select>
</div>

View file

@ -0,0 +1,19 @@
<script setup lang="ts">
import settings_updater_core from "./settings_updater_core.vue";
</script>
<template>
<div>
<div class="alert alert-warning" role="alert">
The updater might not working, yet! Please update manually if you are
running into problems!
</div>
<div class="alert alert-warning" role="alert">
The updater doesnt contain the server related parts, yet! We are
discussing this topic actually, feel free contributing with your opinion
on Discord!
</div>
<settings_updater_core />
</div>
</template>

View file

@ -69,8 +69,11 @@ export async function getVersion() {
let data = await apiGet("/version").then((res) => {
return res;
});
return data.version;
//return data["version"];
if (typeof data !== "undefined" && typeof data.version !== "undefined") {
return data.version;
}
return 0;
}
export async function getConfig() {
@ -139,10 +142,18 @@ export async function getModemState() {
return await apiGet("/modem/state");
}
export async function setRadioParameters(frequency, mode, rf_level) {
export async function setRadioParametersFrequency(frequency) {
return await apiPost("/radio", {
radio_frequency: frequency,
});
}
export async function setRadioParametersMode(mode) {
return await apiPost("/radio", {
radio_mode: mode,
});
}
export async function setRadioParametersRFLevel(rf_level) {
return await apiPost("/radio", {
radio_rf_level: rf_level,
});
}

View file

@ -16,6 +16,7 @@ import {
getModemState,
} from "./api";
import { processFreedataMessages } from "./messagesHandler.ts";
import { processRadioStatus } from "./radioHandler.ts";
// ----------------- init pinia stores -------------
import { setActivePinia } from "pinia";
@ -24,7 +25,10 @@ setActivePinia(pinia);
import { useStateStore } from "../store/stateStore.js";
const stateStore = useStateStore(pinia);
import { settingsStore as settings } from "../store/settingsStore.js";
import {
settingsStore as settings,
getRemote,
} from "../store/settingsStore.js";
export function connectionFailed(endpoint, event) {
stateStore.modem_connection = "disconnected";
@ -96,6 +100,7 @@ export function eventDispatcher(data) {
getAudioDevices();
getSerialDevices();
getFreedataMessages();
processRadioStatus();
return;
case "stopped":
@ -109,6 +114,7 @@ export function eventDispatcher(data) {
getAudioDevices();
getSerialDevices();
getFreedataMessages();
processRadioStatus();
return;
case "failed":
@ -128,13 +134,20 @@ export function eventDispatcher(data) {
message = "Connected to server";
displayToast("success", "bi-ethernet", message, 5000);
stateStore.modem_connection = "connected";
getRemote().then(() => {
//initConnections();
getModemState();
});
//getConfig();
getModemState();
getOverallHealth();
getConfig();
getAudioDevices();
getSerialDevices();
getFreedataMessages();
processFreedataMessages();
processRadioStatus();
return;

View file

@ -64,7 +64,7 @@ export function sortByPropertyDesc(property) {
* @returns true or false if callsign appears to be valid with an SSID
*/
export function validateCallsignWithSSID(callsign: string) {
var patt = new RegExp("^[A-Z]+[0-9][A-Z]*-(1[0-5]|[0-9])$");
var patt = new RegExp("^[A-Za-z0-9]{1,7}-[0-9]{1,3}$");
callsign = callsign;
if (
callsign === undefined ||
@ -85,7 +85,7 @@ export function validateCallsignWithSSID(callsign: string) {
* @returns true or false if callsign appears to be valid without an SSID
*/
export function validateCallsignWithoutSSID(callsign: string) {
var patt = new RegExp("^[A-Z]+[0-9][A-Z]+$");
var patt = new RegExp("^[A-Za-z0-9]{1,7}$");
if (
callsign === undefined ||

View file

@ -82,7 +82,6 @@ function createSortedMessagesList(data: {
}
export function newMessage(dxcall, body, attachments) {
console.log(attachments);
sendFreedataMessage(dxcall, body, attachments);
}

View file

@ -0,0 +1,18 @@
// pinia store setup
import { setActivePinia } from "pinia";
import pinia from "../store/index";
setActivePinia(pinia);
import { settingsStore as settings, onChange } from "../store/settingsStore.js";
import { useStateStore } from "../store/stateStore";
const stateStore = useStateStore(pinia);
import { getRadioStatus } from "./api";
export async function processRadioStatus() {
let result = await getRadioStatus();
stateStore.mode = result.radio_mode;
stateStore.frequency = result.radio_frequency;
stateStore.rf_level = result.radio_rf_level;
}

View file

@ -29,23 +29,8 @@ nconf.file({ file: configPath });
//They should be an exact mirror (variable wise) of settingsStore.local
//Nothing else should be needed aslong as components are using v-bind
// +++
nconf.defaults({
local: {
host: "127.0.0.1",
port: "5000",
spectrum: "waterfall",
wf_theme: 2,
update_channel: "alpha",
enable_sys_notification: false,
grid_layout: "[]",
grid_preset: "[]",
grid_enabled: true,
},
});
nconf.required(["local:host", "local:port"]);
export const settingsStore = reactive({
const defaultConfig = {
local: {
host: "127.0.0.1",
port: "5000",
@ -69,7 +54,6 @@ export const settingsStore = reactive({
enable_protocol: false,
},
MODEM: {
enable_fft: false,
enable_fsk: false,
enable_low_bandwidth_mode: false,
respond_to_cq: false,
@ -104,7 +88,7 @@ export const settingsStore = reactive({
STATION: {
enable_explorer: false,
enable_stats: false,
mycall: "",
mycall: "DEFAULT",
myssid: 0,
mygrid: "",
ssid_list: [],
@ -113,8 +97,16 @@ export const settingsStore = reactive({
tci_ip: "127.0.0.1",
tci_port: 0,
},
MESSAGES: {
enable_auto_repeat: false,
},
},
});
};
nconf.defaults(defaultConfig);
nconf.required(["local:host", "local:port"]);
export const settingsStore = reactive(defaultConfig);
//Save settings for GUI to config file
settingsStore.local = nconf.get("local");
@ -128,7 +120,13 @@ export function onChange() {
export function getRemote() {
return getConfig().then((conf) => {
settingsStore.remote = conf;
if (typeof conf !== "undefined") {
settingsStore.remote = conf;
onChange();
} else {
console.warn("Received undefined configuration, using default!");
settingsStore.remote = defaultConfig.remote;
}
});
}

View file

@ -54,6 +54,9 @@ class ARQDataTypeHandler:
def dispatch(self, type_byte: int, data: bytearray):
session_type = self.get_session_type_from_value(type_byte)
self.state_manager.setARQ(False)
if session_type and session_type in self.handlers and 'handle' in self.handlers[session_type]:
return self.handlers[session_type]['handle'](data)
else:
@ -61,6 +64,9 @@ class ARQDataTypeHandler:
def failed(self, type_byte: int, data: bytearray):
session_type = self.get_session_type_from_value(type_byte)
self.state_manager.setARQ(False)
if session_type in self.handlers and 'failed' in self.handlers[session_type]:
return self.handlers[session_type]['failed'](data)
else:
@ -74,6 +80,9 @@ class ARQDataTypeHandler:
def transmitted(self, type_byte: int, data: bytearray):
session_type = self.get_session_type_from_value(type_byte)
self.state_manager.setARQ(False)
if session_type in self.handlers and 'transmitted' in self.handlers[session_type]:
return self.handlers[session_type]['transmitted'](data)
else:

View file

@ -98,7 +98,6 @@ class ARQSession():
if isinstance(received_data, bytearray) and isinstance(type_byte, int):
self.arq_data_type_handler.dispatch(type_byte, received_data)
self.states.setARQ(False)
return
self.log(f"Ignoring unknown transition from state {self.state.name} with frame {frame['frame_type']}")

View file

@ -96,9 +96,7 @@ class ARQSessionIRS(arq_session.ARQSession):
self.log(f"Waiting {timeout} seconds...")
if not self.event_frame_received.wait(timeout):
self.log("Timeout waiting for ISS. Session failed.")
self.session_ended = time.time()
self.set_state(IRS_State.FAILED)
self.event_manager.send_arq_session_finished(False, self.id, self.dxcall, False, self.state.name, statistics=self.calculate_session_statistics())
self.transmission_failed()
def launch_transmit_and_wait(self, frame, timeout, mode):
thread_wait = threading.Thread(target = self.transmit_and_wait,
@ -208,11 +206,7 @@ class ARQSessionIRS(arq_session.ARQSession):
flag_checksum=False)
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
self.log("CRC fail at the end of transmission!")
self.session_ended = time.time()
self.set_state(IRS_State.FAILED)
self.event_manager.send_arq_session_finished(
False, self.id, self.dxcall, False, self.state.name, statistics=self.calculate_session_statistics())
return False, False
self.transmission_failed()
def calibrate_speed_settings(self):
self.speed_level = 0 # for now stay at lowest speed level
@ -236,4 +230,13 @@ class ARQSessionIRS(arq_session.ARQSession):
self.set_state(IRS_State.ABORTED)
self.event_manager.send_arq_session_finished(
False, self.id, self.dxcall, False, self.state.name, statistics=self.calculate_session_statistics())
return None, None
return None, None
def transmission_failed(self, irs_frame=None):
# final function for failed transmissions
self.session_ended = time.time()
self.set_state(IRS_State.FAILED)
self.log(f"Transmission failed!")
self.event_manager.send_arq_session_finished(True, self.id, self.dxcall,False, self.state.name, statistics=self.calculate_session_statistics())
self.states.setARQ(False)
return None, None

View file

@ -182,7 +182,6 @@ class ARQSessionISS(arq_session.ARQSession):
self.states.setARQ(False)
self.arq_data_type_handler.failed(self.type_byte, self.data)
return None, None
def abort_transmission(self, irs_frame=None):

View file

@ -22,14 +22,18 @@ class ARQRawCommand(TxCommand):
self.data = base64.b64decode(apiParams['data'])
def run(self, event_queue: Queue, modem):
self.emit_event(event_queue)
self.logger.info(self.log_message())
try:
self.emit_event(event_queue)
self.logger.info(self.log_message())
prepared_data, type_byte = self.arq_data_type_handler.prepare(self.data, self.type)
prepared_data, type_byte = self.arq_data_type_handler.prepare(self.data, self.type)
iss = ARQSessionISS(self.config, modem, self.dxcall, self.state_manager, prepared_data, type_byte)
if iss.id:
self.state_manager.register_arq_iss_session(iss)
iss.start()
return iss
except Exception as e:
self.log(f"Error starting ARQ session: {e}", isWarning=True)
iss = ARQSessionISS(self.config, modem, self.dxcall, self.state_manager, prepared_data, type_byte)
if iss.id:
self.state_manager.register_arq_iss_session(iss)
iss.start()
return iss
return False

View file

@ -27,24 +27,26 @@ class SendMessageCommand(TxCommand):
if not first_queued_message:
self.log("No queued message in database.")
return
try:
self.log(f"Queued message found: {first_queued_message['id']}")
DatabaseManagerMessages(self.event_manager).update_message(first_queued_message["id"], update_data={'status': 'transmitting'})
message_dict = DatabaseManagerMessages(self.event_manager).get_message_by_id(first_queued_message["id"])
message = MessageP2P.from_api_params(message_dict['origin'], message_dict)
self.log(f"Queued message found: {first_queued_message['id']}")
DatabaseManagerMessages(self.event_manager).update_message(first_queued_message["id"], update_data={'status': 'transmitting'})
message_dict = DatabaseManagerMessages(self.event_manager).get_message_by_id(first_queued_message["id"])
message = MessageP2P.from_api_params(message_dict['origin'], message_dict)
# Convert JSON string to bytes (using UTF-8 encoding)
payload = message.to_payload().encode('utf-8')
json_bytearray = bytearray(payload)
data, data_type = self.arq_data_type_handler.prepare(json_bytearray, ARQ_SESSION_TYPES.p2pmsg_lzma)
# Convert JSON string to bytes (using UTF-8 encoding)
payload = message.to_payload().encode('utf-8')
json_bytearray = bytearray(payload)
data, data_type = self.arq_data_type_handler.prepare(json_bytearray, ARQ_SESSION_TYPES.p2pmsg_lzma)
iss = ARQSessionISS(self.config,
modem,
self.message.destination,
self.state_manager,
data,
data_type
)
iss = ARQSessionISS(self.config,
modem,
self.message.destination,
self.state_manager,
data,
data_type
)
self.state_manager.register_arq_iss_session(iss)
iss.start()
self.state_manager.register_arq_iss_session(iss)
iss.start()
except Exception as e:
self.log(f"Error starting ARQ session: {e}", isWarning=True)

View file

@ -1,10 +1,10 @@
[NETWORK]
modemport = 3050
modemport = 5000
[STATION]
mycall = XX1XXX
mygrid = JN18cv
myssid = 6
mycall = AA1AAA
mygrid = AA12aa
myssid = 1
ssid_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
enable_explorer = True
enable_stats = True
@ -21,7 +21,7 @@ ip = 127.0.0.1
port = 4532
path =
command =
arguments = --cenas
arguments =
[RADIO]
control = disabled
@ -50,8 +50,11 @@ tuning_range_fmin = -50
enable_fsk = False
enable_low_bandwidth_mode = False
enable_morse_identifier = False
respond_to_cq = False
respond_to_cq = True
rx_buffer_size = 64
tx_delay = 200
beacon_interval = 90
beacon_interval = 300
[MESSAGES]
enable_auto_repeat = False

View file

@ -31,7 +31,6 @@ class CONFIG:
'control': str,
'serial_port': str,
'model_id': int,
'serial_port': str,
'serial_speed': int,
'data_bits': int,
'stop_bits': int,
@ -56,7 +55,6 @@ class CONFIG:
'enable_protocol': bool,
},
'MODEM': {
'enable_fft': bool,
'tuning_range_fmax': int,
'tuning_range_fmin': int,
'enable_fsk': bool,
@ -68,12 +66,22 @@ class CONFIG:
'tx_delay': int,
'beacon_interval': int,
},
'MESSAGES': {
'enable_auto_repeat': bool,
}
}
default_values = {
list: '[]',
bool: 'False',
int: '0',
str: '',
}
def __init__(self, configfile: str):
# set up logger
self.log = structlog.get_logger("CONFIG")
self.log = structlog.get_logger(type(self).__name__)
# init configparser
self.parser = configparser.ConfigParser(inline_comment_prefixes="#", allow_no_value=True)
@ -88,6 +96,9 @@ class CONFIG:
# check if config file exists
self.config_exists()
# validate config structure
self.validate_config()
def config_exists(self):
"""
check if config file exists
@ -99,7 +110,7 @@ class CONFIG:
return False
# Validates config data
def validate(self, data):
def validate_data(self, data):
for section in data:
for setting in data[section]:
if not isinstance(data[section][setting], self.config_types[section][setting]):
@ -107,6 +118,39 @@ class CONFIG:
f" '{data[section][setting]}' {type(data[section][setting])} given.")
raise ValueError(message)
def validate_config(self):
"""
Updates the configuration file to match exactly what is defined in self.config_types.
It removes sections and settings not defined there and adds missing sections and settings.
"""
existing_sections = self.parser.sections()
# Remove sections and settings not defined in self.config_types
for section in existing_sections:
if section not in self.config_types:
self.parser.remove_section(section)
self.log.info(f"[CFG] Removing undefined section: {section}")
continue
existing_settings = self.parser.options(section)
for setting in existing_settings:
if setting not in self.config_types[section]:
self.parser.remove_option(section, setting)
self.log.info(f"[CFG] Removing undefined setting: {section}.{setting}")
# Add missing sections and settings from self.config_types
for section, settings in self.config_types.items():
if section not in existing_sections:
self.parser.add_section(section)
self.log.info(f"[CFG] Adding missing section: {section}")
for setting, value_type in settings.items():
if not self.parser.has_option(section, setting):
default_value = self.default_values.get(value_type, None)
self.parser.set(section, setting, str(default_value))
self.log.info(f"[CFG] Adding missing setting: {section}.{setting}")
return self.write_to_file()
# Handle special setting data type conversion
# is_writing means data from a dict being writen to the config file
# if False, it means the opposite direction
@ -132,8 +176,7 @@ class CONFIG:
# Sets and writes config data from a dict containing data settings
def write(self, data):
# Validate config data before writing
self.validate(data)
self.validate_data(data)
for section in data:
# init section if it doesn't exist yet
if not section.upper() in self.parser.keys():
@ -142,8 +185,13 @@ class CONFIG:
for setting in data[section]:
new_value = self.handle_setting(
section, setting, data[section][setting], True)
self.parser[section][setting] = str(new_value)
try:
self.parser[section][setting] = str(new_value)
except Exception as e:
self.log.error("[CFG] error setting config key", e=e)
return self.write_to_file()
def write_to_file(self):
# Write config data to file
try:
with open(self.config_name, 'w') as configfile:
@ -157,7 +205,7 @@ class CONFIG:
"""
read config file
"""
self.log.info("[CFG] reading...")
#self.log.info("[CFG] reading...")
if not self.config_exists():
return False

View file

@ -24,7 +24,6 @@ class explorer():
self.config = self.config_manager.read()
self.states = states
self.explorer_url = "https://api.freedata.app/explorer.php"
self.publish_interval = 120
def push(self):
self.config = self.config_manager.read()
@ -40,11 +39,10 @@ class explorer():
# stop pushing if default callsign
if callsign in ['XX1XXX-6']:
# Reschedule the push method
self.scheduler.enter(self.publish_interval, 1, self.push)
return
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
# disabled this one
# log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
headers = {"Content-Type": "application/json"}
station_data = {'callsign': callsign, 'gridsquare': gridsquare, 'frequency': frequency, 'strength': strength, 'band': band, 'version': version, 'bandwidth': bandwidth, 'beacon': beacon, "lastheard": []}

View file

@ -4,6 +4,7 @@ import data_frame_factory
import frame_handler
import datetime
from message_system_db_beacon import DatabaseManagerBeacon
from message_system_db_messages import DatabaseManagerMessages
from message_system_db_manager import DatabaseManager
@ -15,3 +16,7 @@ class BeaconFrameHandler(frame_handler.FrameHandler):
self.details["snr"],
self.details['frame']["gridsquare"]
)
if self.config["MESSAGES"]["enable_auto_repeat"]:
# set message to queued if beacon received
DatabaseManagerMessages(self.event_manager).set_message_to_queued_for_callsign(self.details['frame']["origin"])

View file

@ -2,6 +2,9 @@ import frame_handler_ping
import helpers
import data_frame_factory
import frame_handler
from message_system_db_messages import DatabaseManagerMessages
class CQFrameHandler(frame_handler_ping.PingFrameHandler):
def should_respond(self):
@ -14,3 +17,7 @@ class CQFrameHandler(frame_handler_ping.PingFrameHandler):
self.details['snr']
)
self.transmit(qrv_frame)
if self.config["MESSAGES"]["enable_auto_repeat"]:
# set message to queued if CQ received
DatabaseManagerMessages(self.event_manager).set_message_to_queued_for_callsign(self.details['frame']["origin"])

View file

@ -15,7 +15,10 @@ import hmac
import os
import sys
from pathlib import Path
import platform
import subprocess
import psutil
import glob
log = structlog.get_logger("helpers")
@ -701,9 +704,69 @@ def set_flag(byte, flag_name, value, flag_dict):
position = flag_dict[flag_name]
return set_bit(byte, position, value)
def get_flag(byte, flag_name, flag_dict):
"""Get the value of the flag from the byte according to the flag dictionary."""
if flag_name not in flag_dict:
raise ValueError(f"Unknown flag name: {flag_name}")
position = flag_dict[flag_name]
return get_bit(byte, position)
def find_binary_path(binary_name="rigctld", search_system_wide=False):
"""
Search for a binary within the current working directory and its subdirectories.
Optionally, check system-wide locations and PATH environment variable if not found.
:param binary_name: The base name of the binary to search for, without extension.
:param search_system_wide: Boolean flag to enable or disable system-wide search.
:return: The full path to the binary if found, otherwise None.
"""
# Adjust binary name for Windows
if platform.system() == 'Windows':
binary_name += ".exe"
# Search in the current working directory and subdirectories
root_path = os.getcwd()
for dirpath, dirnames, filenames in os.walk(root_path):
if binary_name in filenames:
return os.path.join(dirpath, binary_name)
# If system-wide search is enabled, look in system locations and PATH
if search_system_wide:
system_paths = os.environ.get('PATH', '').split(os.pathsep)
# Optionally add common binary locations for Unix-like and Windows systems
if platform.system() != 'Windows':
system_paths.extend(['/usr/bin', '/usr/local/bin', '/bin'])
else:
system_paths.extend(glob.glob("C:\\Program Files\\Hamlib*\\bin"))
system_paths.extend(glob.glob("C:\\Program Files (x86)\\Hamlib*\\bin"))
for path in system_paths:
potential_path = os.path.join(path, binary_name)
if os.path.isfile(potential_path):
return potential_path
def kill_and_execute(binary_path, additional_args=None):
"""
Kills any running instances of the binary across Linux, macOS, and Windows, then starts a new one non-blocking.
:param binary_path: The full path to the binary to execute.
:param additional_args: A list of additional arguments to pass to the binary.
:return: subprocess.Popen object of the started process
"""
# Kill any existing instances of the binary
for proc in psutil.process_iter(attrs=['pid', 'name', 'cmdline']):
try:
cmdline = proc.info['cmdline']
# Ensure cmdline is iterable and not None
if cmdline and binary_path in ' '.join(cmdline):
proc.kill()
print(f"Killed running instance with PID: {proc.info['pid']}")
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass # Process no longer exists or no permission to kill
# Execute the binary with additional arguments non-blocking
command = [binary_path] + (additional_args if additional_args else [])
return subprocess.Popen(command)

View file

@ -171,21 +171,27 @@ class DatabaseManagerMessages(DatabaseManager):
finally:
session.remove()
def increment_message_attempts(self, message_id):
session = self.get_thread_scoped_session()
def increment_message_attempts(self, message_id, session=None):
own_session = False
if not session:
session = self.get_thread_scoped_session()
own_session = True
try:
message = session.query(P2PMessage).filter_by(id=message_id).first()
if message:
message.attempt += 1
session.commit()
if own_session:
session.commit()
self.log(f"Incremented attempt count for message {message_id}")
else:
self.log(f"Message with ID {message_id} not found")
except Exception as e:
session.rollback()
if own_session:
session.rollback()
self.log(f"An error occurred while incrementing attempts for message {message_id}: {e}")
finally:
session.remove()
if own_session:
session.remove()
def mark_message_as_read(self, message_id):
session = self.get_thread_scoped_session()
@ -201,4 +207,42 @@ class DatabaseManagerMessages(DatabaseManager):
session.rollback()
self.log(f"An error occurred while marking message {message_id} as read: {e}")
finally:
session.remove()
session.remove()
def set_message_to_queued_for_callsign(self, callsign):
session = self.get_thread_scoped_session()
try:
# Find the 'failed' status object
failed_status = session.query(Status).filter_by(name='failed').first()
# Find the 'queued' status object
queued_status = session.query(Status).filter_by(name='queued').first()
# Ensure both statuses are found
if not failed_status or not queued_status:
self.log("Failed or queued status not found", isWarning=True)
return
# Query for messages with the specified callsign, 'failed' status, and fewer than 10 attempts
message = session.query(P2PMessage) \
.filter(P2PMessage.destination_callsign == callsign) \
.filter(P2PMessage.status_id == failed_status.id) \
.filter(P2PMessage.attempt < 10) \
.first()
if message:
# Increment attempt count using the existing function
self.increment_message_attempts(message.id, session)
message.status_id = queued_status.id
self.log(f"Set message {message.id} to queued and incremented attempt")
session.commit()
return {'status': 'success', 'message': f'{len(message)} message(s) set to queued'}
else:
return {'status': 'failure', 'message': 'No eligible messages found'}
except Exception as e:
session.rollback()
self.log(f"An error occurred while setting messages to queued: {e}", isWarning=True)
return {'status': 'failure', 'message': str(e)}
finally:
session.remove()

View file

@ -20,8 +20,8 @@ class RadioManager:
def _init_rig_control(self):
# Check how we want to control the radio
if self.radiocontrol == "rigctld":
self.radio = rigctld.radio(self.state_manager, hostname=self.rigctld_ip,port=self.rigctld_port)
if self.radiocontrol in ["rigctld", "rigctld_bundle"]:
self.radio = rigctld.radio(self.config, self.state_manager, hostname=self.rigctld_ip,port=self.rigctld_port)
elif self.radiocontrol == "tci":
raise NotImplementedError
# self.radio = self.tci_module

View file

@ -1,6 +1,6 @@
import socket
import structlog
import time
import helpers
import threading
class radio:
@ -8,11 +8,12 @@ class radio:
log = structlog.get_logger("radio (rigctld)")
def __init__(self, states, hostname="localhost", port=4532, timeout=5):
def __init__(self, config, states, hostname="localhost", port=4532, timeout=5):
self.hostname = hostname
self.port = port
self.timeout = timeout
self.states = states
self.config = config
self.connection = None
self.connected = False
@ -29,6 +30,10 @@ class radio:
'ptt': False # Initial PTT state is set to False
}
# start rigctld...
if self.config["RADIO"]["control"] in ["rigctld_bundle"]:
self.start_service()
# connect to radio
self.connect()
@ -45,7 +50,8 @@ class radio:
def disconnect(self):
self.connected = False
self.connection.close()
if self.connection:
self.connection.close()
del self.connection
self.connection = None
self.states.set("radio_status", False)
@ -197,7 +203,66 @@ class radio:
self.parameters['alc'] = self.send_command('l ALC')
self.parameters['strength'] = self.send_command('l STRENGTH')
self.parameters['rf'] = self.send_command('l RFPOWER') # RF, RFPOWER
self.parameters['rf'] = int(float(self.send_command('l RFPOWER')) * 100) # RF, RFPOWER
"""Return the latest fetched parameters."""
return self.parameters
def start_service(self):
binary_name = "rigctld"
binary_path = helpers.find_binary_path(binary_name, search_system_wide=True)
additional_args = self.format_rigctld_args()
if binary_path:
self.log.info(f"Rigctld binary found at: {binary_path}")
helpers.kill_and_execute(binary_path, additional_args)
self.log.info(f"Executed rigctld...")
else:
self.log.warning("Rigctld binary not found.")
def format_rigctld_args(self):
config = self.config['RADIO'] # Accessing the 'RADIO' section of the INI file
config_rigctld = self.config['RIGCTLD'] # Accessing the 'RIGCTLD' section of the INI file for custom args
args = []
# Helper function to check if the value should be ignored
def should_ignore(value):
return value in ['ignore', 0]
# Model ID, Serial Port, and Speed
if not should_ignore(config.get('model_id')):
args += ['-m', str(config['model_id'])]
if not should_ignore(config.get('serial_port')):
args += ['-r', config['serial_port']]
if not should_ignore(config.get('serial_speed')):
args += ['-s', str(config['serial_speed'])]
# PTT Port and Type
if not should_ignore(config.get('ptt_port')):
args += ['--ptt-port', config['ptt_port']]
if not should_ignore(config.get('ptt_type')):
args += ['--ptt-type', config['ptt_type']]
# Serial DCD and DTR
if not should_ignore(config.get('serial_dcd')):
args += ['--dcd-type', config['serial_dcd']]
if not should_ignore(config.get('serial_dtr')):
args += ['--set-conf', f'dtr_state={config["serial_dtr"]}']
# Handling Data Bits and Stop Bits
if not should_ignore(config.get('data_bits')):
args += ['--set-conf', f'data_bits={config["data_bits"]}']
if not should_ignore(config.get('stop_bits')):
args += ['--set-conf', f'stop_bits={config["stop_bits"]}']
# Fixme #rts_state
# if not should_ignore(config.get('rts_state')):
# args += ['--set-conf', f'stop_bits={config["rts_state"]}']
# Handle custom arguments for rigctld
# Custom args are split via ' ' so python doesn't add extranaeous quotes on windows
args += config_rigctld["arguments"].split(" ")
#print("Hamlib args ==>" + str(args))
return args

View file

@ -21,7 +21,7 @@ class ScheduleManager:
self.scheduler = sched.scheduler(time.time, time.sleep)
self.events = {
'check_for_queued_messages': {'function': self.check_for_queued_messages, 'interval': 10},
'explorer_publishing': {'function': self.push_to_explorer, 'interval': 120},
'explorer_publishing': {'function': self.push_to_explorer, 'interval': 60},
'transmitting_beacon': {'function': self.transmit_beacon, 'interval': self.beacon_interval},
'beacon_cleanup': {'function': self.delete_beacons, 'interval': 600},
}
@ -70,7 +70,7 @@ class ScheduleManager:
cmd.run(self.event_manager, self.modem)
def delete_beacons(self):
DatabaseManagerBeacon(self.event_manager).beacon_cleanup_older_than_days(14)
DatabaseManagerBeacon(self.event_manager).beacon_cleanup_older_than_days(2)
def push_to_explorer(self):
self.config = self.config_manager.read()

View file

@ -29,7 +29,7 @@ app = Flask(__name__)
CORS(app)
CORS(app, resources={r"/*": {"origins": "*"}})
sock = Sock(app)
MODEM_VERSION = "0.13.2-alpha"
MODEM_VERSION = "0.13.6-alpha"
# set config file to use
def set_config():
@ -72,11 +72,14 @@ def validate(req, param, validator, isRequired = True):
# Takes a transmit command and puts it in the transmit command queue
def enqueue_tx_command(cmd_class, params = {}):
command = cmd_class(app.config_manager.read(), app.state_manager, app.event_manager, params)
app.logger.info(f"Command {command.get_name()} running...")
if command.run(app.modem_events, app.service_manager.modem): # TODO remove the app.modem_event custom queue
return True
return False
try:
command = cmd_class(app.config_manager.read(), app.state_manager, app.event_manager, params)
app.logger.info(f"Command {command.get_name()} running...")
if command.run(app.modem_events, app.service_manager.modem): # TODO remove the app.modem_event custom queue
return True
except Exception as e:
app.logger.warning(f"Command {command.get_name()} failed...: {e}")
return False
## REST API
@app.route('/', methods=['GET'])
@ -94,10 +97,10 @@ def index():
def config():
if request.method in ['POST']:
set_config = app.config_manager.write(request.json)
app.modem_service.put("restart")
if not set_config:
response = api_response(None, 'error writing config')
else:
app.modem_service.put("restart")
response = api_response(set_config)
return response
elif request.method == 'GET':
@ -222,19 +225,23 @@ def post_modem_send_raw_stop():
if not app.state_manager.is_modem_running:
api_abort('Modem not running', 503)
for id in app.state_manager.arq_irs_sessions:
app.state_manager.arq_irs_sessions[id].abort_transmission()
for id in app.state_manager.arq_iss_sessions:
app.state_manager.arq_iss_sessions[id].abort_transmission()
if app.state_manager.getARQ():
for id in app.state_manager.arq_irs_sessions:
app.state_manager.arq_irs_sessions[id].abort_transmission()
for id in app.state_manager.arq_iss_sessions:
app.state_manager.arq_iss_sessions[id].abort_transmission()
return api_response(request.json)
@app.route('/radio', methods=['GET', 'POST'])
def get_post_radio():
if request.method in ['POST']:
app.radio_manager.set_frequency(request.json['radio_frequency'])
app.radio_manager.set_mode(request.json['radio_mode'])
app.radio_manager.set_rf_level(int(request.json['radio_rf_level']))
if "radio_frequency" in request.json:
app.radio_manager.set_frequency(request.json['radio_frequency'])
if "radio_mode" in request.json:
app.radio_manager.set_mode(request.json['radio_mode'])
if "radio_rf_level" in request.json:
app.radio_manager.set_rf_level(int(request.json['radio_rf_level']))
return api_response(request.json)
elif request.method == 'GET':
@ -244,11 +251,12 @@ def get_post_radio():
def get_post_freedata_message():
if request.method in ['GET']:
result = DatabaseManagerMessages(app.event_manager).get_all_messages_json()
return api_response(result, 200)
if enqueue_tx_command(command_message_send.SendMessageCommand, request.json):
return api_response(request.json, 200)
else:
api_abort('Error executing command...', 500)
return api_response(result)
if request.method in ['POST']:
enqueue_tx_command(command_message_send.SendMessageCommand, request.json)
return api_response(request.json)
api_abort('Error executing command...', 500)
@app.route('/freedata/messages/<string:message_id>', methods=['GET', 'POST', 'PATCH', 'DELETE'])
def handle_freedata_message(message_id):

View file

@ -103,7 +103,7 @@ class TestARQSession(unittest.TestCase):
def waitForSession(self, q, outbound = False):
key = 'arq-transfer-outbound' if outbound else 'arq-transfer-inbound'
while True:
while True and self.channels_running:
ev = q.get()
if key in ev and ('success' in ev[key] or 'ABORTED' in ev[key]):
self.logger.info(f"[{threading.current_thread().name}] {key} session ended.")
@ -125,16 +125,17 @@ class TestARQSession(unittest.TestCase):
def waitAndCloseChannels(self):
self.waitForSession(self.iss_event_queue, True)
self.channels_running = False
self.waitForSession(self.irs_event_queue, False)
self.channels_running = False
def testARQSessionSmallPayload(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 0
self.loss_probability = 30
self.establishChannels()
params = {
'dxcall': "XX1XXX-1",
'dxcall': "AA1AAA-1",
'data': base64.b64encode(bytes("Hello world!", encoding="utf-8")),
'type': "raw_lzma"
}
@ -149,7 +150,7 @@ class TestARQSession(unittest.TestCase):
self.establishChannels()
params = {
'dxcall': "XX1XXX-1",
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(1000)),
'type': "raw_lzma"
}
@ -165,7 +166,7 @@ class TestARQSession(unittest.TestCase):
self.establishChannels()
params = {
'dxcall': "XX1XXX-1",
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(100)),
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
@ -184,7 +185,7 @@ class TestARQSession(unittest.TestCase):
self.establishChannels()
params = {
'dxcall': "XX1XXX-1",
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(100)),
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
@ -200,7 +201,7 @@ class TestARQSession(unittest.TestCase):
def testSessionCleanupISS(self):
params = {
'dxcall': "XX1XXX-1",
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(100)),
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)

View file

@ -1,3 +1,5 @@
import sys
sys.path.append('modem')
import unittest
import config
@ -11,8 +13,8 @@ class TestConfigMethods(unittest.TestCase):
c = config.CONFIG('modem/config.ini.example')
self.assertTrue(c.config_exists())
c = config.CONFIG('modem/nonexistant.ini')
self.assertFalse(c.config_exists())
#c = config.CONFIG('modem/nonexistant')
#self.assertFalse(c.config_exists())
def test_read(self):
data = self.config.read()
@ -42,10 +44,10 @@ class TestConfigMethods(unittest.TestCase):
def test_validate_data(self):
data = {'STATION': {'ssid_list': "abc"}}
with self.assertRaises(ValueError):
self.config.validate(data)
self.config.validate_data(data)
data = {'STATION': {'ssid_list': [1, 2, 3]}}
self.assertIsNone(self.config.validate(data))
self.assertIsNone(self.config.validate_data(data))
if __name__ == '__main__':

View file

@ -108,7 +108,7 @@ class TestMessageProtocol(unittest.TestCase):
def waitForSession(self, q, outbound=False):
key = 'arq-transfer-outbound' if outbound else 'arq-transfer-inbound'
while True:
while True and self.channels_running:
ev = q.get()
if key in ev and ('success' in ev[key] or 'ABORTED' in ev[key]):
self.logger.info(f"[{threading.current_thread().name}] {key} session ended.")
@ -130,6 +130,7 @@ class TestMessageProtocol(unittest.TestCase):
def waitAndCloseChannels(self):
self.waitForSession(self.iss_event_queue, True)
self.channels_running = False
self.waitForSession(self.irs_event_queue, False)
self.channels_running = False
@ -139,7 +140,7 @@ class TestMessageProtocol(unittest.TestCase):
self.establishChannels()
params = {
'destination': "XX1XXX-1",
'destination': "AA1AAA-1",
'body': 'Hello World',
}

View file

@ -51,7 +51,7 @@ class TestProtocols(unittest.TestCase):
def testPingWithAck(self):
# Run ping command
api_params = { "dxcall": "XX1XXX-6"}
api_params = { "dxcall": "AA1AAA-1"}
ping_cmd = PingCommand(self.config, self.state_manager, self.event_manager, api_params)
#ping_cmd.run(self.event_queue, self.modem)
frame = ping_cmd.test(self.event_queue)