@ham2k/lib-operation-data 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "@ham2k/lib-operation-data",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
7
7
  ".": "./src/index.js"
8
8
  },
9
9
  "devDependencies": {
10
+ "jest": "~29",
10
11
  "standard": "^17.0.0"
12
+ },
13
+ "scripts": {
14
+ "test": "node --experimental-vm-modules ./node_modules/.bin/jest"
15
+ },
16
+ "standard": {
17
+ "env": [ "jest" ]
11
18
  }
12
19
  }
@@ -0,0 +1,141 @@
1
+ {
2
+ "sources": [
3
+ { "url": "https://www.iaru-r2.org/en/reference/band-plans/" },
4
+ { "url": "https://www.arrl.org/band-plan" },
5
+ { "url": "https://www.arrl.org/news/view/updated-arrl-us-amateur-radio-bands-charts-now-available" }
6
+ ],
7
+ "bands": {
8
+ "160m": {
9
+ "mhz": [1800, 2000],
10
+ "segments": [
11
+ { "name": "CW", "mhz": [1800, 1843], "mode": "CW" },
12
+ { "name": "Data", "mhz": [1800, 1810], "mode": "RTTY" },
13
+ { "name": "FT8", "mhz": [1840, 1843], "mode": "FT8" },
14
+ { "name": "Phone", "mhz": [1843, 2000], "mode": "SSB", "submode": "LSB" }
15
+ ]
16
+ },
17
+ "80m": {
18
+ "mhz": [3500, 3800],
19
+ "segments": [
20
+ { "name": "CW", "mhz": [3500, 3600], "mode": "CW" },
21
+ { "name": "Phone", "mhz": [3535, 3800], "mode": "SSB", "submode": "LSB", "regions": [ 3 ] },
22
+ { "name": "FT8", "mhz": [3568, 3571], "mode": "FT8", "regions": [ 3 ] },
23
+ { "name": "Data", "mhz": [3570, 3600], "mode": "RTTY" },
24
+ { "name": "FT8", "mhz": [3573, 3576], "mode": "FT8" },
25
+ { "name": "Phone", "mhz": [3600, 4000], "mode": "SSB", "submode": "LSB" }
26
+ ]
27
+ },
28
+ "60m": {
29
+ "mhz": [5330.5, 3406.5],
30
+ "segments": [
31
+ { "name": "60m Channel 1", "mhz": [5330.5, 5333.5] },
32
+ { "name": "60m Channel 2", "mhz": [5346.5, 5349.5] },
33
+ { "name": "60m Channel 3", "mhz": [5357, 5360], "mode": "FT8" },
34
+ { "name": "60m Channel 4", "mhz": [5371.5, 5373.5] },
35
+ { "name": "60m Channel 5", "mhz": [5403.5, 5406.5] }
36
+ ]
37
+ },
38
+ "40m": {
39
+ "mhz": [7000, 7300],
40
+ "segments": [
41
+ { "name": "CW", "mhz": [7000, 7060], "mode": "CW" },
42
+ { "name": "CW", "mhz": [7000, 7125], "mode": "CW", "countries": [ "US" ] },
43
+ { "name": "FT4", "mhz": [7047.5, 7050.5], "mode": "FT4" },
44
+ { "name": "Phone", "mhz": [7060, 7300], "mode": "SSB", "submode": "LSB" },
45
+ { "name": "FT8", "mhz": [7074, 7077], "mode": "FT8" },
46
+ { "name": "Data", "mhz": [7080, 7125], "mode": "RTTY" },
47
+ { "name": "Phone", "mhz": [7125, 7300], "mode": "SSB", "submode": "LSB", "countries": [ "US" ] }
48
+ ]
49
+ },
50
+ "30m": {
51
+ "mhz": [10100, 10150],
52
+ "segments": [
53
+ { "name": "CW", "mhz": [10100, 10150], "mode": "CW" },
54
+ { "name": "Data", "mhz": [10130, 10140], "mode": "RTTY" },
55
+ { "name": "FT8", "mhz": [10136, 10139], "mode": "FT8" },
56
+ { "name": "FT4", "mhz": [10140, 10143], "mode": "FT4" }
57
+ ]
58
+ },
59
+ "20m": {
60
+ "mhz": [14000, 14350],
61
+ "segments": [
62
+ { "name": "CW", "mhz": [14000, 14101], "mode": "CW", "regions": [ 2 ] },
63
+ { "name": "CW", "mhz": [14000, 14150], "mode": "CW" },
64
+ { "name": "Data", "mhz": [14070, 14095], "mode": "RTTY" },
65
+ { "name": "FT8", "mhz": [14074, 14077], "mode": "FT8" },
66
+ { "name": "FT4", "mhz": [14080, 14083], "mode": "FT4" },
67
+ { "name": "Phone", "mhz": [14112, 14350], "mode": "SSB", "submode": "USB", "regions": [ 2 ] },
68
+ { "name": "Phone", "mhz": [14150, 14350], "mode": "SSB", "submode": "USB", "countries": [ "US" ] }
69
+ ]
70
+ },
71
+ "17m": {
72
+ "mhz": [18068, 18168],
73
+ "segments": [
74
+ { "name": "CW", "mhz": [18068, 18110], "mode": "CW" },
75
+ { "name": "Data", "mhz": [18100, 18105], "mode": "RTTY" },
76
+ { "name": "FT8", "mhz": [18100, 18103], "mode": "FT8" },
77
+ { "name": "FT4", "mhz": [18104, 18107], "mode": "FT4" },
78
+ { "name": "Phone", "mhz": [18110, 18168], "mode": "SSB", "submode": "USB" }
79
+ ]
80
+ },
81
+ "15m": {
82
+ "mhz": [21000, 21450],
83
+ "segments": [
84
+ { "name": "CW", "mhz": [21000, 21150], "mode": "CW" },
85
+ { "name": "Data", "mhz": [21070, 21095], "mode": "RTTY" },
86
+ { "name": "FT8", "mhz": [21074, 21077], "mode": "FT8" },
87
+ { "name": "FT4", "mhz": [21140, 21143], "mode": "FT4" },
88
+ { "name": "Phone", "mhz": [21150, 21450], "mode": "SSB", "submode": "USB" }
89
+ ]
90
+ },
91
+ "12m": {
92
+ "mhz": [24890, 24990],
93
+ "segments": [
94
+ { "name": "CW", "mhz": [24890, 24930], "mode": "CW" },
95
+ { "name": "FT8", "mhz": [24915, 24918], "mode": "FT8" },
96
+ { "name": "FT4", "mhz": [24919, 23922], "mode": "FT4" },
97
+ { "name": "Data", "mhz": [24920, 24925], "mode": "RTTY" },
98
+ { "name": "Phone", "mhz": [24930, 24990], "mode": "SSB", "submode": "USB" }
99
+ ]
100
+ },
101
+ "10m": {
102
+ "mhz": [28000, 29700],
103
+ "segments": [
104
+ { "name": "CW", "mhz": [28000, 28190], "mode": "CW" },
105
+ { "name": "Data", "mhz": [28070, 28150], "mode": "RTTY" },
106
+ { "name": "FT8", "mhz": [28074, 28077], "mode": "FT8" },
107
+ { "name": "FT4", "mhz": [28180, 28183], "mode": "FT4" },
108
+ { "name": "Beacons", "mhz": [28190, 28300] },
109
+ { "name": "Phone SSB", "mhz": [28300, 29000], "mode": "SSB", "submode": "USB" },
110
+ { "name": "AM", "mhz": [29000, 29200], "mode": "AM" },
111
+ { "name": "Satellite", "mhz": [29300, 29520] },
112
+ { "name": "Repeater Uplinks", "mhz": [29520, 29590] },
113
+ { "name": "FM", "mhz": [29520, 29700], "mode": "FM" },
114
+ { "name": "Repeater Downlinks", "mhz": [29620, 29700] }
115
+ ]
116
+ },
117
+ "6m": {
118
+ "mhz": [50000, 54000],
119
+ "segments": [
120
+ { "name": "CW", "mhz": [50000, 50150], "mode": "CW" },
121
+ { "name": "Data", "mhz": [50090, 50130], "mode": "RTTY" },
122
+ { "name": "Phone", "mhz": [50150, 50600], "mode": "SSB", "submode": "USB" },
123
+ { "name": "AM", "mhz": [50150, 54000], "mode": "AM" },
124
+ { "name": "FT8", "mhz": [50313, 50316], "mode": "FT8" },
125
+ { "name": "FT4", "mhz": [50318, 50321], "mode": "FT4" },
126
+ { "name": "FT8", "mhz": [50323, 50326], "mode": "FT8" }
127
+ ]
128
+ },
129
+ "2m": {
130
+ "mhz": [144000, 148000],
131
+ "segments": [
132
+ { "name": "CW", "mhz": [144000, 144100], "mode": "CW" },
133
+ { "name": "Data", "mhz": [144100, 144200], "mode": "RTTY" },
134
+ { "name": "FT8", "mhz": [144174, 144177], "mode": "FT8" },
135
+ { "name": "FT8", "mhz": [144170, 144173], "mode": "FT4" },
136
+ { "name": "Phone", "mhz": [144200, 144275], "mode": "SSB", "submode": "LSB" },
137
+ { "name": "FM", "mhz": [144300, 148000], "mode": "FM" }
138
+ ]
139
+ }
140
+ }
141
+ }
package/src/lib/modes.js CHANGED
@@ -1,3 +1,5 @@
1
+ import BandPlans from '../data/bandPlans.json'
2
+
1
3
  export const SUPER_MODES = [
2
4
  'CW',
3
5
  'PHONE',
@@ -144,3 +146,35 @@ export function superModeForMode(mode) {
144
146
  return 'DATA'
145
147
  }
146
148
  }
149
+
150
+ const AllSegments = Object.keys(BandPlans.bands).reduce((segments, band) => {
151
+ return segments.concat(
152
+ BandPlans.bands[band].segments.map(segment => (
153
+ {
154
+ ...segment,
155
+ band,
156
+ width: segment.mhz[1] - segment.mhz[0],
157
+ regions: (segment.regions || []).reduce((regions, region) => { regions[region] = true; return regions }, {}),
158
+ entities: (segment.entities || []).reduce((entities, entity) => { entities[entity] = true; return entities }, {}),
159
+ countries: (segment.countries || []).reduce((countries, country) => { countries[country] = true; return countries }, {}),
160
+ }
161
+ ))
162
+ )
163
+ }, [])
164
+
165
+ export function modeForFrequency(frequency, { region, country, entity } = {}) {
166
+ const segments = AllSegments.filter(segment => segment.mhz[0] <= frequency && segment.mhz[1] >= frequency)
167
+ const sortedSegments = segments.sort((a, b) => {
168
+ if (entity && !a.entities[entity] && b.entities[entity]) return 1
169
+ if (entity && a.entities[entity] && !b.entities[entity]) return -1
170
+
171
+ if (country && !a.countries[country] && b.countries[country]) return 1
172
+ if (country && a.countries[country] && !b.countries[country]) return -1
173
+
174
+ if (region && !a.regions[region] && b.regions[region]) return 1
175
+ if (region && a.regions[region] && !b.regions[region]) return -1
176
+
177
+ return a.width - b.width
178
+ })
179
+ return sortedSegments[0]?.mode
180
+ }
@@ -0,0 +1,14 @@
1
+ import { modeForFrequency } from './modes'
2
+
3
+ describe('modeForFrequency', () => {
4
+ it('should find the most common mode for a frequency', () => {
5
+ expect(modeForFrequency(14255)).toEqual('USB')
6
+ expect(modeForFrequency(14107)).toEqual('CW')
7
+ expect(modeForFrequency(14074)).toEqual('FT8')
8
+
9
+ expect(modeForFrequency(14140)).toEqual('CW')
10
+ expect(modeForFrequency(14140, { region: 2 })).toEqual('USB')
11
+ expect(modeForFrequency(14140, { entity: 'K' })).toEqual('CW')
12
+
13
+ })
14
+ })