diff options
Diffstat (limited to 'sdnr/wt/odlux/apps/linkCalculationApp')
6 files changed, 631 insertions, 374 deletions
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/package.json b/sdnr/wt/odlux/apps/linkCalculationApp/package.json index 171770603..c03afe19b 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/package.json +++ b/sdnr/wt/odlux/apps/linkCalculationApp/package.json @@ -29,8 +29,8 @@ "@types/react": "17.0.3", "@types/react-dom": "17.0.2", "@types/react-router-dom": "5.1.7", - "@material-ui/core": "4.11.0", - "@material-ui/icons": "4.9.1", + "@material-ui/core": "4.11.4", + "@material-ui/icons": "4.11.2", "@types/classnames": "2.2.6", "@types/flux": "3.1.8", "@types/jquery": "3.3.10", diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml b/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml index 5467c8b5d..c5d8c3617 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml +++ b/sdnr/wt/odlux/apps/linkCalculationApp/pom.xml @@ -140,8 +140,8 @@ <!-- optional: default phase is "generate-resources" --> <phase>initialize</phase> <configuration> - <nodeVersion>v10.16.3</nodeVersion> - <yarnVersion>v1.19.0</yarnVersion> + <nodeVersion>v12.13.0</nodeVersion> + <yarnVersion>v1.22.10</yarnVersion> </configuration> </execution> <execution> diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts index e7427e4cc..0849058dc 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/actions/commonLinkCalculationActions.ts @@ -21,98 +21,155 @@ import { Dispatch } from "../../../../framework/src/flux/store"; import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; -export class UpdateLinkIdAction extends Action{ - constructor(public linkId: string){ +export class UpdateLinkIdAction extends Action { + constructor(public linkId: string) { super(); } } -export class UpdateFrequencyAction extends Action{ - constructor(public frequency: number){ +export class UpdateFrequencyAction extends Action { + constructor(public frequency: number) { super(); } } -export class UpdateSiteAction extends Action{ +export class UpdateSiteAction extends Action { constructor( public siteA?: any, public siteB?: any - ){ + ) { super(); } } -export class UpdateRainAttAction extends Action{ - - constructor(public rainAtt: number){ +export class UpdateRainAttAction extends Action { + + constructor(public rainAtt: number) { super(); } } -export class UpdateRainValAction extends Action{ - constructor(public rainVal: number){ +export class UpdateRainValAction extends Action { + constructor(public rainVal: number) { super(); } } -export class updateHideForm extends Action{ - constructor(public formView: boolean){ +export class updateHideForm extends Action { + constructor(public formView: boolean) { super(); } } -export class UpdateDistanceAction extends Action{ - constructor(public distance: number){ +export class UpdateDistanceAction extends Action { + constructor(public distance: number) { super(); } } -export class UpdateFslCalculation extends Action{ - constructor(public fsl: number){ +export class UpdateFslCalculation extends Action { + constructor(public fsl: number) { super(); } } -export class UpdateLatLonAction extends Action{ +export class UpdateLatLonAction extends Action { constructor( public Lat1: number, - public Lon1:number, - public Lat2: number, + public Lon1: number, + public Lat2: number, public Lon2: number - ){ + ) { + super(); + + } +} +export class UpdatePolAction extends Action { + constructor(public polarization: string) { super(); - } } -export class UpdatePolAction extends Action{ - constructor(public polarization: string){ +export class isCalculationServerReachableAction extends Action { + constructor(public reachable: boolean) { super(); } } -export class isCalculationServerReachableAction extends Action{ - constructor(public reachable: boolean){ +export class updateAltitudeAction extends Action { + constructor( + public amslA: number, + public aglA: number, + public amslB: number, + public aglB: number + ) { super(); } } -export class updateAltitudeAction extends Action{ +export class UpdateAbsorptionLossAction extends Action { constructor( - public amslA:number, - public aglA:number, - public amslB:number, - public aglB:number - ){ + public absorptionOxygen: number, + public absorptionWater: number, + + ) { + super(); + } +} +export class UpdateWorstMonthRainAction extends Action { + constructor(public month: string) { + super(); + } +} + +export class UpdateEIRPAction extends Action { + constructor(public eirpA: number,public eirpB: number) { + super(); + } +} +export class UpdateAntennaGainAction extends Action { + constructor(public antennaGainList: string[]) { + super(); + } +} +export class UpdateAntennaListAction extends Action { + constructor(public antennaList: string[]) { + super(); + } +} +export class UpdateAntennaAction extends Action { + constructor(public antennaA: string | null, public antennaB : string | null) { + super(); + } +} +export class UpdateRadioAttributesAction extends Action { + constructor(public som: number , public eirpA : number, public eirpB : number) { super(); } } -export class UpdateAbsorptionLossAction extends Action{ - constructor( - public absorptionOxygen:number, - public absorptionWater:number, - - ){ - super(); - } +export class UpdateTxPowerAction extends Action { + constructor(public txPowerA: string | null , public txPowerB : string | null) { + super(); + } } -export class UpdateWorstMonthRainAction extends Action{ - constructor(public month: string){ +export class UpdateRxSensitivityAction extends Action { + constructor(public rxSensitivityA: string | null , public rxSensitivityB : string | null) { super(); } } + +export const updateAntennaList = (frequency: number) => async (dispatcher: Dispatch, getState: () => IApplicationStoreState) => { + let antennaList: string[] = [] + let antennaDiameterList: string[] = [] + let antennaGainList :string[] =[] + //switch case here frequency = 26? antennaList.push + switch (frequency) { + case 7: antennaList.push('ANDREW VHLPX2.5-7W', 'ANDREW VHLPX3-7W', 'ANDREW VHLPX4-7W', 'ANDREW VHLPX6-7W' ), antennaDiameterList.push('0.6','0.9','1.2','1.8'), antennaGainList.push('33.90','35.50','37.30','40.61'); break + case 11: antennaList.push('ANDREW VHLPX2-11W', 'ANDREW VHLPX3-11W', 'ANDREW VHLPX4-11W'), antennaDiameterList.push('0.6','0.9','1.2'), antennaGainList.push('34.50','38.4','40.70');break + case 15: antennaList.push('ANDREW VHLPX1-15', 'ANDREW VHLPX2-15', 'ANDREW VHLPX3-15', 'ANDREW VHLPX4-15'), antennaDiameterList.push('0.3','0.6','0.9','1.2'), antennaGainList.push('32.00','36.80','41.11','42.90');break + case 23: antennaList.push('ANDREW VHLPX1-23', 'ANDREW VHLPX2-23', 'ANDREW VHLPX3-23', 'ANDREW VHLPX4-23'), antennaDiameterList.push('0.3','0.6','0.9','1.2'), antennaGainList.push('35.30','40.21','44.80','46.71');break + case 26: antennaList.push('ANDREW VHLPX1-26', 'ANDREW VHLPX2-26', 'ANDREW VHLPX3-26'), antennaDiameterList.push('0.3','0.6','0.9'), antennaGainList.push('36.61','40.21','41.21','45.80');break + case 28: antennaList.push('ANDREW VHLPX1-28', 'ANDREW VHLPX2-28'), antennaDiameterList.push('0.3','0.6'), antennaGainList.push('38.11','42.21');break + case 38: antennaList.push('ANDREW VHLPX1-38', 'ANDREW VHLPX2-38'), antennaDiameterList.push('0.3','0.6'), antennaGainList.push('40.11','45.21');break + case 42: antennaList.push('ANDREW VHLPX1-42-XXX/D', 'ANDREW VHLPX2-42-XXX/A'), antennaDiameterList.push('0.3','0.6'), antennaGainList.push('40.80','46.00');break + case 80: antennaList.push('Radio Waves HPCPE-80', 'Radio Waves HPLP2-80'), antennaDiameterList.push('0.3','0.6'), antennaGainList.push('43.80','50.80');break + } + dispatcher(new UpdateAntennaListAction(antennaList)) + dispatcher(new UpdateAntennaGainAction(antennaGainList)) +} + diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts index 608367072..edfad052a 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/handlers/linkCalculationAppRootHandler.ts @@ -21,7 +21,7 @@ import { combineActionHandler } from '../../../../framework/src/flux/middleware' // ** do not remove ** import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; import { IActionHandler } from '../../../../framework/src/flux/action';; -import { UpdateLinkIdAction, UpdateFrequencyAction , UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, updateHideForm, UpdateFslCalculation, UpdateSiteAction, UpdateDistanceAction, isCalculationServerReachableAction, UpdatePolAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction} from '../actions/commonLinkCalculationActions'; +import { UpdateLinkIdAction, UpdateFrequencyAction , UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, updateHideForm, UpdateFslCalculation, UpdateSiteAction, UpdateDistanceAction, isCalculationServerReachableAction, UpdatePolAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction, UpdateEIRPAction, UpdateAntennaAction, UpdateAntennaListAction, UpdateAntennaGainAction, UpdateTxPowerAction, UpdateRxSensitivityAction} from '../actions/commonLinkCalculationActions'; declare module '../../../../framework/src/store/applicationStore' { interface IApplicationStoreState { @@ -55,7 +55,20 @@ export type ILinkCalculationAppStateState= { aglB:number, absorptionWater:number, absorptionOxygen: number, - month: string + month: string, + eirpA: number, + eirpB: number, + antennaGainA: number, + antennaGainB :number, + antennaList:string[], + antennaGainList:string[], + antennaA: string, + antennaB:string, + systemOperatingMargin : number, + txPowerA : string, + txPowerB: string, + rxSensitivityA : string, + rxSensitivityB: string } const initialState: ILinkCalculationAppStateState ={ @@ -80,7 +93,20 @@ const initialState: ILinkCalculationAppStateState ={ aglB:0, absorptionWater:0, absorptionOxygen: 0, - month: '' + month: '', + eirpA: 0, + eirpB: 0, + antennaGainA :0, + antennaGainB :0, + antennaList:[], + antennaGainList:[], + antennaA: '0', + antennaB:'0', + systemOperatingMargin : 0, + txPowerA : '0', + txPowerB: '0', + rxSensitivityA: '0', + rxSensitivityB: '0' } @@ -130,6 +156,25 @@ export const LinkCalculationHandler: IActionHandler<ILinkCalculationAppStateStat else if (action instanceof UpdateWorstMonthRainAction){ state = Object.assign({}, state, {month:action.month}) } + else if (action instanceof UpdateEIRPAction){ + state = Object.assign({}, state, {eirpA:action.eirpA, eirpB:action.eirpB}) + } + else if (action instanceof UpdateAntennaGainAction){ + state = Object.assign({}, state, {antennaGainList:action.antennaGainList}) + } + else if (action instanceof UpdateAntennaListAction){ + state = Object.assign({}, state, {antennaList:action.antennaList}) + } + else if (action instanceof UpdateAntennaAction){ + state = Object.assign({}, state, {antennaA:action.antennaA == null ? state.antennaA : action.antennaA , antennaB: action.antennaB == null? state.antennaB : action.antennaB}) + } + else if (action instanceof UpdateTxPowerAction){ + state = Object.assign({}, state, {txPowerA:action.txPowerA == null ? state.txPowerA : action.txPowerA , txPowerB: action.txPowerB == null? state.txPowerB : action.txPowerB}) + } + else if (action instanceof UpdateRxSensitivityAction){ + state = Object.assign({}, state, {rxSensitivityA:action.rxSensitivityA == null ? state.rxSensitivityA : action.rxSensitivityA , rxSensitivityB: action.rxSensitivityB == null? state.rxSensitivityB : action.rxSensitivityB}) + } + return state } diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss index 35a9b9702..e4b0c7797 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/Style.scss @@ -1,11 +1,11 @@ -.parent{ +// .parent{ - display: flex; - justify-content: space-evenly; - margin: auto; +// display: flex; +// justify-content: space-evenly; +// margin: auto; -} +//} .input { width: 150px; box-sizing: border-box; @@ -18,56 +18,99 @@ box-sizing: border-box; } +.container1{ + margin-bottom: 15px; -.container-1 { - height: 50vh; - width: 80%; - justify-content: center; - align-items: baseline;; - display: flex; - flex-direction: row; - align-content: space-between; - padding: 20px 40px; - border-radius: 10px; - // box-shadow: 0px 10px 50px #555; - background-color: #ffffff; - // padding-top: 10px; - } - .column1 { - flex-direction: column; - width: 30%; - align-items: flex-end;; - // padding: 2em; +.container1 div{ + display:flex; + flex-direction: row; + + width:100%; + padding-top: 2px; +} + +.container1 div div{ + width:50%; + border-bottom-style: solid; + border-bottom-width: thin; + border-color: silver; +} + +.firstBox div:first-child{ + margin-left: 33.5%; +} + +// .container-1 { +// width: 80%; +// justify-content: center; +// align-items: baseline;; +// display: flex; +// flex-direction: row; +// align-content: space-between; +// padding: 20px 40px; +// border-radius: 10px; +// // box-shadow: 0px 10px 50px #555; +// background-color: #ffffff; +// // padding-top: 10px; + +// } + + // .column1 { + // flex-direction: column; + // width: 30%; + // align-items: flex-end;; + // // padding: 2em; - } - .column1 div { - margin-top: 10px; - // align-items: space-between; - // flex-wrap: wrap; - border-bottom-style: solid; - border-bottom-width: thin; - border-color: silver; - } - .middlecolumn{ + // } + // .column1 div { + // margin-top: 10px; + // // align-items: space-between; + // // flex-wrap: wrap; + // border-bottom-style: solid; + // border-bottom-width: thin; + // border-color: silver; + // } + // .middlecolumn{ - flex-direction: column; - flex-grow: 1; - // padding: 10px 10px; - } + // flex-direction: column; + // flex-grow: 1; + // // padding: 10px 10px; + // } - .middlecolumn div{ - margin-top: 10px; - border-bottom-style: solid; - border-bottom-width: thin; - border-color: silver; - } + // .middlecolumn div{ + // margin-top: 10px; + // border-bottom-style: solid; + // border-bottom-width: thin; + // border-color: silver; + // } - .column2 { - margin-left: 200px; - } - .column2 div{ - margin-top: 10px; + // .column2 { + // margin-left: 200px; + // } + // .column2 div{ + // margin-top: 10px; - }
\ No newline at end of file + // } + + .antennaContainer{ + margin-bottom: 15px; + background-color: rgb(184, 181, 181); + + } + .antennaContainer div { + display:flex; + flex-direction: row; + + width:100%; + padding-top: 2px; +} +.antennaContainer div div{ + + width:50%; + +} +.antennaFont{ + font-family: "Lucida Console"; +}
\ No newline at end of file diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx index 61a700c71..063926269 100644 --- a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx +++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx @@ -24,10 +24,11 @@ import { TextField, Tabs, Tab, Typography, AppBar, Button, Tooltip, Checkbox, Ta import './Style.scss' import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore"; -import { UpdateFrequencyAction, UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, UpdateFslCalculation, isCalculationServerReachableAction, UpdatePolAction, UpdateDistanceAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction } from "../actions/commonLinkCalculationActions"; +import { UpdateFrequencyAction, UpdateLatLonAction, UpdateRainAttAction, UpdateRainValAction, UpdateFslCalculation, isCalculationServerReachableAction, UpdatePolAction, UpdateDistanceAction, updateAltitudeAction, UpdateAbsorptionLossAction, UpdateWorstMonthRainAction, updateAntennaList, UpdateAntennaAction, UpdateRadioAttributesAction, UpdateTxPowerAction, UpdateRxSensitivityAction } from "../actions/commonLinkCalculationActions"; import { faPlaneArrival, faAlignCenter } from "@fortawesome/free-solid-svg-icons"; import ConnectionInfo from '../components/connectionInfo' import { red } from "@material-ui/core/colors"; +import { Dvr } from "@material-ui/icons"; @@ -41,33 +42,44 @@ const mapProps = (state: IApplicationStoreState) => ({ rainAtt: state.linkCalculation.calculations.rainAtt, rainVal: state.linkCalculation.calculations.rainVal, formView: state.linkCalculation.calculations.formView, - fsl:state.linkCalculation.calculations.fsl, + fsl: state.linkCalculation.calculations.fsl, siteA: state.linkCalculation.calculations.siteA, siteB: state.linkCalculation.calculations.siteB, distance: state.linkCalculation.calculations.distance, - reachable :state.linkCalculation.calculations.reachable, - polarization:state.linkCalculation.calculations.polarization, - amslA:state.linkCalculation.calculations.amslA, - amslB:state.linkCalculation.calculations.amslB, - aglA:state.linkCalculation.calculations.aglA, - aglB:state.linkCalculation.calculations.aglB, - absorptionOxygen : state.linkCalculation.calculations.absorptionOxygen, - absorptionWater : state.linkCalculation.calculations.absorptionWater, - month : state.linkCalculation.calculations.month + reachable: state.linkCalculation.calculations.reachable, + polarization: state.linkCalculation.calculations.polarization, + amslA: state.linkCalculation.calculations.amslA, + amslB: state.linkCalculation.calculations.amslB, + aglA: state.linkCalculation.calculations.aglA, + aglB: state.linkCalculation.calculations.aglB, + absorptionOxygen: state.linkCalculation.calculations.absorptionOxygen, + absorptionWater: state.linkCalculation.calculations.absorptionWater, + month: state.linkCalculation.calculations.month, + eirpSiteA: state.linkCalculation.calculations.eirpA, + eirpSiteB: state.linkCalculation.calculations.eirpB, + antennaGainA: state.linkCalculation.calculations.antennaGainA, + antennaGainB: state.linkCalculation.calculations.antennaGainB, + antennaList: state.linkCalculation.calculations.antennaList, + antennaGainList: state.linkCalculation.calculations.antennaGainList, + antennaA: state.linkCalculation.calculations.antennaA, + antennaB: state.linkCalculation.calculations.antennaB, + systemOperatingMargin : state.linkCalculation.calculations.systemOperatingMargin + }); -const BASE_URL="/topology/linkcalculator" +const BASE_URL = "/topology/linkcalculator" const mapDispatch = (dispatcher: IDispatcher) => ({ updateFrequency: (frequency: number) => { - dispatcher.dispatch(new UpdateFrequencyAction(frequency)) + dispatcher.dispatch(new UpdateFrequencyAction(frequency)) + dispatcher.dispatch(updateAntennaList(frequency)) }, updateLatLon: (Lat1: number, Lon1: number, Lat2: number, Lon2: number) => { dispatcher.dispatch(new UpdateLatLonAction(Lat1, Lon1, Lat2, Lon2)) }, - + updateRainValue: (rainVal: number) => { dispatcher.dispatch(new UpdateRainValAction(rainVal)) }, @@ -80,53 +92,59 @@ const mapDispatch = (dispatcher: IDispatcher) => ({ dispatcher.dispatch(new UpdateRainAttAction(rainAtt)) }, - - FSL :(free:number)=> { - dispatcher.dispatch(new UpdateFslCalculation (free)) - }, - UpdateConectivity : (reachable:boolean) => { - dispatcher.dispatch (new isCalculationServerReachableAction (reachable)) + FSL: (free: number) => { + dispatcher.dispatch(new UpdateFslCalculation(free)) }, - updatePolarization :(polarization:any)=>{ - dispatcher.dispatch (new UpdatePolAction(polarization)) + UpdateConectivity: (reachable: boolean) => { + dispatcher.dispatch(new isCalculationServerReachableAction(reachable)) }, - updateAutoDistance : (distance:number)=>{ - dispatcher.dispatch (new UpdateDistanceAction(distance)) + updatePolarization: (polarization: any) => { + dispatcher.dispatch(new UpdatePolAction(polarization)) }, - UpdateAbsorption : (OxLoss:number , WaterLoss:number) => { - dispatcher.dispatch (new UpdateAbsorptionLossAction (OxLoss, WaterLoss)) + updateAutoDistance: (distance: number) => { + dispatcher.dispatch(new UpdateDistanceAction(distance)) }, - // UpdateWorstMonth : (worstmonth:boolean) => { - // dispatcher.dispatch (new UpdateWorstMonthAction(worstmonth)) - // }, - - UpdateWorstMonthRain : (month:string) => { - dispatcher.dispatch (new UpdateWorstMonthRainAction(month)) - } + UpdateAbsorption: (OxLoss: number, WaterLoss: number) => { + dispatcher.dispatch(new UpdateAbsorptionLossAction(OxLoss, WaterLoss)) + }, + UpdateWorstMonthRain: (month: string) => { + dispatcher.dispatch(new UpdateWorstMonthRainAction(month)) + }, + UpdateAntenas: (antennaA: string | null, antennaB: string | null) => { + dispatcher.dispatch(new UpdateAntennaAction(antennaA, antennaB)) + }, + UpdateRadioAttributes :(som: number, eirpA: number, eirpB: number)=>{ + dispatcher.dispatch(new UpdateRadioAttributesAction(som,eirpA, eirpB)) + }, + UpdateTxPower :(txPowerA: string | null, txPowerB: string | null)=>{ + dispatcher.dispatch(new UpdateTxPowerAction(txPowerA, txPowerB)) + }, + UpdateRxSensitivity :(rxSensitivityA : string | null, rxSensitivityB : string | null)=>{ + dispatcher.dispatch(new UpdateRxSensitivityAction(rxSensitivityA, rxSensitivityB)) + } }); type linkCalculationProps = Connect<typeof mapProps, typeof mapDispatch>; interface initialState { - rainMethodDisplay: boolean, - absorptionMethod : string; + rainMethodDisplay: boolean, + absorptionMethod: string; horizontalBoxChecked: boolean, - latitude1Error: string, - longitude1Error:string - latitude2Error: string, - longitude2Error:string, - frequencyError: string, - rainMethodError: string, - attenuationMethodError : string, - worstmonth : boolean, - showWM : string - - + latitude1Error: string, + longitude1Error: string + latitude2Error: string, + longitude2Error: string, + frequencyError: string, + rainMethodError: string, + antennaTypeError: string, + attenuationMethodError: string, + worstmonth: boolean, + showWM: string, } class LinkCalculation extends React.Component<linkCalculationProps, initialState> { @@ -135,40 +153,41 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState this.state = { rainMethodDisplay: false, horizontalBoxChecked: true, - absorptionMethod : '0', + absorptionMethod: '0', latitude1Error: '', - longitude1Error:'', + longitude1Error: '', latitude2Error: '', - longitude2Error:'', + longitude2Error: '', frequencyError: '', rainMethodError: '', - attenuationMethodError : '', - worstmonth : false, - showWM: '' - }; - } - - updateAutoDistance = async (lat1: number, lon1: number, lat2: number, lon2: number)=>{ - const result = await fetch(BASE_URL+'/distance/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2) - const json = await result.json() - return json.distanceInKm - } + attenuationMethodError: '', + antennaTypeError: '', + worstmonth: false, + showWM: '', + }; + } + + updateAutoDistance = async (lat1: number, lon1: number, lat2: number, lon2: number) => { + const result = await fetch(BASE_URL + '/distance/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2) + const json = await result.json() + return json.distanceInKm + } + + updateLatLon = (e: any) => { + + e.target.id == 'Lat1' ? this.props.updateLatLon(e.target.value, this.props.lon1, this.props.lat2, this.props.lon2) : null + e.target.id == 'Lon1' ? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, this.props.lon2) : null + e.target.id == 'Lat2' ? this.props.updateLatLon(this.props.lat1, this.props.lon1, e.target.value, this.props.lon2) : null + e.target.id == 'Lon2' ? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, e.target.value) : null - updateLatLon = (e:any) => { - - e.target.id== 'Lat1'? this.props.updateLatLon(e.target.value, this.props.lon1, this.props.lat2, this.props.lon2) : null - e.target.id== 'Lon1'? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, this.props.lon2) : null - e.target.id== 'Lat2'? this.props.updateLatLon(this.props.lat1, this.props.lon1, e.target.value, this.props.lon2) : null - e.target.id== 'Lon2'? this.props.updateLatLon(this.props.lat1, e.target.value, this.props.lat2, e.target.value) : null - } - updatePoli = (val: string) =>{ + updatePoli = (val: string) => { - this.setState({horizontalBoxChecked: !this.state.horizontalBoxChecked}); + this.setState({ horizontalBoxChecked: !this.state.horizontalBoxChecked }); this.props.updatePolarization(val); - + } LatLonToDMS = (value: number, isLon: boolean = false) => { @@ -187,266 +206,359 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState } } - rainAttCal = (lat1: any, lon1: any, lat2: any, lon2: any, frequency: any, distance: number, polarization : string, worstmonth:boolean) => { - if(!worstmonth){ - fetch(BASE_URL+'/rain/annual/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + frequency+ '/'+ distance + '/' + polarization.toUpperCase()) - .then(res => res.json()) - .then(result => { this.props.UpdateRainAtt(result.rainAttenuation) ; this.props.updateRainValue(result.rainFall.rainrate)}) + rainAttCal = (lat1: any, lon1: any, lat2: any, lon2: any, frequency: any, distance: number, polarization: string, worstmonth: boolean) => { + if (!worstmonth) { + fetch(BASE_URL + '/rain/annual/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + frequency + '/' + distance + '/' + polarization.toUpperCase()) + .then(res => res.json()) + .then(result => { this.props.UpdateRainAtt(result.rainAttenuation); this.props.updateRainValue(result.rainFall.rainrate) }) } else { - fetch(BASE_URL+'/rain/worstmonth/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + frequency+ '/'+ distance + '/' + polarization.toUpperCase()) - .then(res => res.json()) - .then(result => { this.props.UpdateRainAtt(result.rainAttenuation) ; this.props.updateRainValue(result.rainFall.rainrate); this.props.UpdateWorstMonthRain (result.rainFall.period); this.setState({showWM: '- Wm is : '})}) + fetch(BASE_URL + '/rain/worstmonth/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + frequency + '/' + distance + '/' + polarization.toUpperCase()) + .then(res => res.json()) + .then(result => { this.props.UpdateRainAtt(result.rainAttenuation); this.props.updateRainValue(result.rainFall.rainrate); this.props.UpdateWorstMonthRain(result.rainFall.period); this.setState({ showWM: '- Wm is : ' }) }) } } - manualRain = (rainfall: number, frequency: number, distance:number, polarization : string) => { - fetch(BASE_URL+'/rain/' + rainfall + '/' + frequency + '/' + distance+ '/' + polarization.toUpperCase()) + manualRain = (rainfall: number, frequency: number, distance: number, polarization: string) => { + fetch(BASE_URL + '/rain/' + rainfall + '/' + frequency + '/' + distance + '/' + polarization.toUpperCase()) .then(res => res.json()) .then(result => { this.props.specificRain(result.rainAttenuation) }) - } + } + + FSL = (distance: number, frequency: number) => { + fetch(BASE_URL + '/fsl/' + distance + '/' + frequency) + .then(res => res.json()) + .then(result => { this.props.FSL(result.fspl) }) + } - FSL = (distance:number, frequency:number) => { - fetch(BASE_URL+'/fsl/' + distance + '/' + frequency) - .then(res=>res.json()) - .then (result => {this.props.FSL(result.fspl)}) + AbsorptionAtt = (lat1: number, lon1: number, lat2: number, lon2: number, distance: number, frequency: number, worstmonth: boolean, absorptionMethod: string) => { + if (!worstmonth) { + fetch(BASE_URL + '/absorption/annual/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + distance + '/' + frequency + '/' + absorptionMethod) + .then(res => res.json()) + .then(result => { this.props.UpdateAbsorption(result.oxygenLoss, result.waterLoss) }) } - - AbsorptionAtt =(lat1: number, lon1: number, lat2: number, lon2: number, distance:number, frequency:number, worstmonth:boolean, absorptionMethod : string) => { - if(!worstmonth) - { - fetch(BASE_URL+'/absorption/annual/' +lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + distance + '/' + frequency + '/' +absorptionMethod) - .then(res=>res.json()) - .then (result => {this.props.UpdateAbsorption(result.oxygenLoss, result.waterLoss)}) - } - else { - fetch(BASE_URL+'/absorption/annual/' +lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + distance + '/' + frequency + '/' +absorptionMethod) - .then(res=>res.json()) - .then (result => {this.props.UpdateAbsorption(result.oxygenLoss, result.waterLoss)}) - } + else { + fetch(BASE_URL + '/absorption/annual/' + lat1 + ',' + lon1 + ',' + lat2 + ',' + lon2 + '/' + distance + '/' + frequency + '/' + absorptionMethod) + .then(res => res.json()) + .then(result => { this.props.UpdateAbsorption(result.oxygenLoss, result.waterLoss) }) } + } + + linkBudget = (antennaA: string, antennaB: string, transmissionPowerA: number, transmissionPowerB: number) => { + fetch(BASE_URL + '/linkbudget/' + antennaA + '/' + antennaB + '/' + transmissionPowerA + '/' + transmissionPowerB) + .then(res=>res.json()) + .then(result => {this.props.UpdateRadioAttributes(result.systemOperatingMargin, result.eirpA, result.eirpB)}) + } + + formValid = () => { + + this.props.lat1 === 0 ? this.setState({ latitude1Error: 'Enter a number between -90 to 90' }) : null + this.props.lat2 === 0 ? this.setState({ latitude2Error: 'Enter a number between -90 to 90' }) : null + this.props.lon1 === 0 ? this.setState({ longitude1Error: 'Enter a number between -180 to 180' }) : null + this.props.lon2 === 0 ? this.setState({ longitude2Error: 'Enter a number between -180 to 180' }) : null + this.props.frequency === 0 ? this.setState({ frequencyError: 'Select a frequency' }) : this.setState({ frequencyError: '' }) + + this.state.rainMethodDisplay === null && this.props.rainVal === 0 ? this.setState({ rainMethodError: 'Select the rain method' }) : this.setState({ rainMethodError: '' }) + this.state.absorptionMethod === '0' ? this.setState({ attenuationMethodError: 'Select the attenuation method' }) : this.setState({ attenuationMethodError: '' }) + console.log(this.state); + console.log(this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !== 0 && this.props.frequency !== 0 && this.state.rainMethodError === '' && this.state.attenuationMethodError === ''); + + return this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !== 0 && this.props.frequency !== 0 && this.state.rainMethodError === '' && this.state.attenuationMethodError === ''; + + } + + - formValid = () => { - - this.props.lat1 === 0 ? this.setState({latitude1Error: 'Enter a number between -90 to 90'}) : null - this.props.lat2 === 0 ? this.setState({latitude2Error: 'Enter a number between -90 to 90'}) : null - this.props.lon1 === 0 ? this.setState({longitude1Error: 'Enter a number between -180 to 180' }) : null - this.props.lon2 === 0 ? this.setState({longitude2Error: 'Enter a number between -180 to 180' }) : null - this.props.frequency === 0 ? this.setState({frequencyError: 'Select a frequency' }) : this.setState({frequencyError: ''}) - - this.state.rainMethodDisplay === null && this.props.rainVal === 0 ? this.setState({rainMethodError: 'Select the rain method'}) : this.setState({rainMethodError: ''}) - this.state.absorptionMethod === '0' ? this.setState({attenuationMethodError: 'Select the attenuation method'}) : this.setState({attenuationMethodError: ''}) - console.log(this.state); - console.log(this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !==0 && this.props.frequency!==0 && this.state.rainMethodError==='' && this.state.attenuationMethodError=== ''); - - return this.props.lat1 !== 0 && this.props.lat2 !== 0 && this.props.lon1 !== 0 && this.props.lon2 !==0 && this.props.frequency!==0 && this.state.rainMethodError==='' && this.state.attenuationMethodError=== ''; - - } - - - buttonHandler = async () => { - - if (this.formValid()) { + + if (this.formValid()) { this.props.updateAutoDistance(await this.updateAutoDistance(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2)) this.FSL(this.props.distance, this.props.frequency) - if (this.state.worstmonth===false) { - this.setState({showWM : ' '}) + if (this.state.worstmonth === false) { + this.setState({ showWM: ' ' }) this.props.UpdateWorstMonthRain('') - this.AbsorptionAtt (this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth, this.state.absorptionMethod) + this.AbsorptionAtt(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth, this.state.absorptionMethod) - if (this.state.rainMethodDisplay === true){ + if (this.state.rainMethodDisplay === true) { - this.manualRain(this.props.rainVal, this.props.frequency, this.props.distance, this.props.polarization!); + this.manualRain(this.props.rainVal, this.props.frequency, this.props.distance, this.props.polarization!); } else { // this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.state.worstmonth) this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization!, this.state.worstmonth); } - } - else { - this.AbsorptionAtt (this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth, this.state.absorptionMethod) + } + else { + this.AbsorptionAtt(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.distance, this.props.frequency, this.state.worstmonth, this.state.absorptionMethod) - // this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.state.worstmonth) + // this.updateRainValue(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.state.worstmonth) - this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization!, this.state.worstmonth); + this.rainAttCal(this.props.lat1, this.props.lon1, this.props.lat2, this.props.lon2, this.props.frequency, this.props.distance, this.props.polarization!, this.state.worstmonth); } } - else console.log('form is not valid') + else console.log('form is not valid') } componentDidMount = () => { - fetch (BASE_URL+'/fsl/1/1') - .then(res => {if (res.ok) { this.props.UpdateConectivity(true)}else {this.props.UpdateConectivity(false)} }) - .catch (res => {this.props.UpdateConectivity(false)} ) + fetch(BASE_URL + '/fsl/1/1') + .then(res => { if (res.ok) { this.props.UpdateConectivity(true) } else { this.props.UpdateConectivity(false) } }) + .catch(res => { this.props.UpdateConectivity(false) }) } - handleChange =(e:any) => { - - switch (e.target.id){ - case 'Lat1' : if ( e.target.value >90 || e.target.value<-90 ) - { this.setState({latitude1Error: 'Enter a number between -90 to 90'})} - else {this.updateLatLon(e) - this.setState({latitude1Error: ''}) } - break; - case 'Lat2' : if ( e.target.value >90 || e.target.value<-90 ) - { this.setState({latitude2Error: 'Enter a number between -90 to 90'})} - else {this.updateLatLon(e) - this.setState({latitude2Error: ''}) } - break; - case 'Lon1' : if ( e.target.value >180 || e.target.value<-180 ) - { this.setState({longitude1Error: 'Enter a number between -180 to 180'})} - else {this.updateLatLon(e) - this.setState({longitude1Error: ''}) } - break; - case 'Lon2' : if ( e.target.value >180 || e.target.value<-180 ) - { this.setState({longitude2Error: 'Enter a number between -180 to 180'})} - else {this.updateLatLon(e) - this.setState({longitude2Error: ''}) } - break; - + handleChange = (e: any) => { + + switch (e.target.id) { + case 'Lat1': if (e.target.value > 90 || e.target.value < -90) { this.setState({ latitude1Error: 'Enter a number between -90 to 90' }) } + else { + this.updateLatLon(e) + this.setState({ latitude1Error: '' }) + } + break; + case 'Lat2': if (e.target.value > 90 || e.target.value < -90) { this.setState({ latitude2Error: 'Enter a number between -90 to 90' }) } + else { + this.updateLatLon(e) + this.setState({ latitude2Error: '' }) + } + break; + case 'Lon1': if (e.target.value > 180 || e.target.value < -180) { this.setState({ longitude1Error: 'Enter a number between -180 to 180' }) } + else { + this.updateLatLon(e) + this.setState({ longitude1Error: '' }) + } + break; + case 'Lon2': if (e.target.value > 180 || e.target.value < -180) { this.setState({ longitude2Error: 'Enter a number between -180 to 180' }) } + else { + this.updateLatLon(e) + this.setState({ longitude2Error: '' }) + } + break; + } } - render() { + render() { return ( - - <div > - - {!this.props.formView && - - <div className = 'parent'> - - <div >Site A - <form > - <label>Latitude: <input aria-label="site-a-latitude-input" className={this.state.latitude1Error.length>0 ? 'error' : 'input'} id='Lat1' type='number' onChange={(e: any) => {this.handleChange(e)} }/></label> - <div style={{fontSize:12, color:'red'}}> {this.state.latitude1Error} </div></form> - <form><label>Longitude: <input aria-label="site-a-longitude-input" className={this.state.longitude1Error.length>0 ? 'error' : 'input'} id='Lon1' type='number' onChange={(e: any) => this.handleChange(e) } /></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude1Error} </div> - </form> - </div> - - <div>Site B - <form> - <label>Latitude: <input aria-label="site-b-latitude-input" className={this.state.latitude2Error.length>0 ? 'error' : 'input'} id='Lat2' type='number' onChange={(e: any) => {this.handleChange(e) }} /></label><div style={{fontSize:12, color:'red'}}> {this.state.latitude2Error} </div></form> - <form><label>Longitude: <input aria-label="site-b-longitude-input" className={this.state.longitude2Error.length>0 ? 'error' : 'input'} id='Lon2' type='number' onChange={(e: any) => {this.handleChange(e) } }/></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude2Error} </div></form> - </div> - + + <div > + + {!this.props.formView && + + <div className='container1'> + <div className='firstBox'> + <div>SiteA</div> + <div>SiteB</div> + </div> + + <div className='firstBox'> + <div> + <form > + <label>Latitude: <input aria-label="site-a-latitude-input" className={this.state.latitude1Error.length > 0 ? 'error' : 'input'} id='Lat1' type='number' onChange={(e: any) => { this.handleChange(e) }} /></label> + <div style={{ fontSize: 12, color: 'red' }}> {this.state.latitude1Error} </div> + </form></div> + <div> + <form> + <label>Latitude: <input aria-label="site-b-latitude-input" className={this.state.latitude2Error.length > 0 ? 'error' : 'input'} id='Lat2' type='number' onChange={(e: any) => { this.handleChange(e) }} /></label><div style={{ fontSize: 12, color: 'red' }}> {this.state.latitude2Error} </div> + </form></div> + </div> + + <div className='firstBox'> + <div> + <form><label>Longitude: <input aria-label="site-a-longitude-input" className={this.state.longitude1Error.length > 0 ? 'error' : 'input'} id='Lon1' type='number' onChange={(e: any) => this.handleChange(e)} /></label><div style={{ fontSize: 12, color: 'red' }}> {this.state.longitude1Error} </div> + </form></div> + <div> + <form><label>Longitude: <input aria-label="site-b-longitude-input" className={this.state.longitude2Error.length > 0 ? 'error' : 'input'} id='Lon2' type='number' onChange={(e: any) => { this.handleChange(e) }} /></label><div style={{ fontSize: 12, color: 'red' }}> {this.state.longitude2Error} </div></form> + </div> + </div> + + + </div> } - <div className='container-1'> - <div>{<form><input aria-label="annual" type='checkbox' id='Annual' value ="Annual" checked= {this.state.worstmonth===false} onClick= {(e: any) => this.setState ({worstmonth: false})}></input>Annual - <input aria-label="worst-month" style={{marginLeft:10}} type='checkbox' id='Worst Month' value ="Worst" checked= {this.state.worstmonth===true} onClick= {(e:any)=>this.setState ({worstmonth: true})}></input>WM</form>}</div> - - - <div className='column1'> - <div> </div> - {(this.props.siteA.length>0 || this.props.siteB.length>0) && <div >Site Name</div>} - <div>Latitude</div> - <div>Longitude</div> - <div>Azimuth</div> - <div>Average Mean Sea Level</div> - <div>Antenna Height Above Ground</div> - <div>Distance</div> - <div style={{marginTop:20}}>Polarization</div> - <div style={{marginTop:20}}>Frequency</div> - <div>Free Space Loss</div> - <div style={{marginTop:10}}>Rain Model</div> - <div style={{marginTop:20}}>Rainfall Rate</div> - <div>Rain Loss</div> - <div style={{marginTop:18}}>Absorption Model</div> - <div>Oxygen Specific Attenuation</div> - <div>Water Vapor Specific Attenuation</div> + <div className='container1'> + <div >{<form><input aria-label="annual" type='checkbox' id='Annual' value="Annual" checked={this.state.worstmonth === false} onClick={(e: any) => this.setState({ worstmonth: false })}></input>Annual + <input aria-label="worst-month" style={{ marginLeft: 10 }} type='checkbox' id='Worst Month' value="Worst" checked={this.state.worstmonth === true} onClick={(e: any) => this.setState({ worstmonth: true })}></input>WM</form>} </div> - - - <div className='middlecolumn'> - <div >Site A</div> - {this.props.siteA.length>0 &&<div> {this.props.siteA }</div>} - <div aria-label="site-a-latitude-dms"> {this.props.lat1 && this.LatLonToDMS(this.props.lat1)}</div> - <div aria-label="site-a-longitude-dms">{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</div> - <div>0</div> - <div aria-label="site-a-amsl">{this.props.amslA.toFixed(2)} m</div> - <div aria-label="site-a-antenna-amsl">{this.props.aglA.toFixed(2)} m</div> - - - <div className='column2'> - <div aria-label="distance-between-sites">{this.props.distance?.toFixed(3)} km</div> - <div>{<form><input aria-label="polarization-horizontal" type='checkbox' id='Horizontal' value ="Horizontal" checked= {this.props.polarization==='Horizontal'} onClick= {(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal - <input aria-label="polarization-vertical" style={{marginLeft:10}} type='checkbox' id='Vertical' value ="Vertical" checked= {this.props.polarization==='Vertical'} onClick= {(e:any)=>{this.props.updatePolarization(e.target.value)}}></input>Vertical</form>}</div> - - <div> {<select aria-label="select-frequency-in-ghz" className={this.state.frequencyError.length>0 ? 'error' : 'input'} onChange={(e) => { this.props.updateFrequency(Number(e.target.value)); e.target.value==='0'? this.setState({frequencyError: 'select a frequency'}): this.setState({frequencyError:''})}}> - - <option value='0' aria-label="none-value" >Select Freq</option> - <option value='7' aria-label="7" >7 GHz</option> - <option value='11' aria-label="11" >11 GHz</option> - <option value='15' aria-label="15" >15 GHz</option> - <option value='23' aria-label="23">23 GHz</option> - <option value='26' aria-label="26">26 GHz</option> - <option value='28' aria-label="28">28 GHz</option> - <option value='38' aria-label="38">38 GHz</option> - <option value='42' aria-label="42">42 GHz</option> - <option value='80' aria-label="80">80 GHz</option> - </select>} <div style={{fontSize:12, color:'red'}}> {this.state.frequencyError} </div> </div> - - <div aria-label="fspl-value">{this.props.fsl.toFixed(3)} dB</div> - - <div> {<select aria-label="select-rain-method" className={this.state.rainMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => {e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false}):this.setState({ rainMethodDisplay: true}); e.target.value==='0'? this.setState({rainMethodError: 'select a Rain model'}): this.setState({rainMethodError:''}) }}> - <option value='0' aria-label="none-value" >Select Rain Method</option> - <option value='itu' aria-label="itur8377">ITU-R P.837-7</option> - <option value='manual' aria-label="manual-entry">Specific Rain</option> - </select>} <div style={{fontSize:12,color:'red'}}>{this.state.rainMethodError}</div> - </div> + <div className='firstBox'> + <div>Site A</div> + <div>Site B</div> + </div> + {/* <div> </div> */} + <div> + {(this.props.siteA.length > 0 || this.props.siteB.length > 0) && <div >Site Name</div>} + <div> {this.props.siteA}</div> + <div> {this.props.siteB}</div> + </div> + <div> + <div>Latitude</div> + <div aria-label="site-a-latitude-dms"> {this.props.lat1 && this.LatLonToDMS(this.props.lat1)}</div> + <div aria-label="site-b-latitude-dms"> {this.props.lat2 && this.LatLonToDMS(this.props.lat2)}</div> + + </div> + <div> + <div>Longitude</div> + <div aria-label="site-a-longitude-dms">{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</div> + <div aria-label="site-b-longitude-dms">{this.props.lon2 && this.LatLonToDMS(this.props.lon2)}</div> + </div> + <div> + <div>Azimuth</div> + <div>0</div> + <div>0</div> + </div> + <div> + <div>Average Mean Sea Level</div> + <div aria-label="site-a-amsl">{this.props.amslA.toFixed(2)} m</div> + <div aria-label="site-b-amsl">{this.props.amslB.toFixed(2)} m</div> + </div> + <div> + <div>Antenna Height Above Ground</div> + <div aria-label="site-a-antenna-amsl">{this.props.aglA.toFixed(2)} m</div> + <div aria-label="site-b-antenna-amsl">{this.props.aglB.toFixed(2)} m</div> + </div> + <div> + <div >Distance</div> + <div aria-label="distance-between-sites">{this.props.distance?.toFixed(3)} km</div> + </div> + <div> + <div >Polarization</div> + <div >{<form><input aria-label="polarization-horizontal" type='checkbox' id='Horizontal' value="Horizontal" checked={this.props.polarization === 'Horizontal'} onClick={(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal + <input aria-label="polarization-vertical" style={{ marginLeft: 10 }} type='checkbox' id='Vertical' value="Vertical" checked={this.props.polarization === 'Vertical'} onClick={(e: any) => { this.props.updatePolarization(e.target.value) }}></input>Vertical</form>}</div> + </div> + <div> + <div style={{ marginTop: 5 }}>Frequency</div> + <div style={{ marginTop: 5 }}> {<select aria-label="select-frequency-in-ghz" className={this.state.frequencyError.length > 0 ? 'error' : 'input'} onChange={(e) => { this.props.updateFrequency(Number(e.target.value)); e.target.value === '0' ? this.setState({ frequencyError: 'select a frequency' }) : this.setState({ frequencyError: '' }); this.props.UpdateAntenas('0', '0') }}> + + <option value='0' aria-label="none-value" >Select Freq</option> + <option value='7' aria-label="7" >7 GHz</option> + <option value='11' aria-label="11" >11 GHz</option> + <option value='15' aria-label="15" >15 GHz</option> + <option value='23' aria-label="23">23 GHz</option> + <option value='26' aria-label="26">26 GHz</option> + <option value='28' aria-label="28">28 GHz</option> + <option value='38' aria-label="38">38 GHz</option> + <option value='42' aria-label="42">42 GHz</option> + <option value='80' aria-label="80">80 GHz</option> + </select>} <div style={{ fontSize: 12, color: 'red' }}> {this.state.frequencyError} </div> </div> + </div> + <div> + <div>Free Space Loss</div> + <div aria-label="fspl-value">{this.props.fsl.toFixed(3)} dB</div> + </div> + <div> + <div>Rain Model</div> + <div> {<select aria-label="select-rain-method" className={this.state.rainMethodError.length > 0 ? 'error' : 'input'} onChange={(e) => { e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false }) : this.setState({ rainMethodDisplay: true }); e.target.value === '0' ? this.setState({ rainMethodError: 'select a Rain model' }) : this.setState({ rainMethodError: '' }) }}> + <option value='0' aria-label="none-value" >Select Rain Method</option> + <option value='itu' aria-label="itur8377">ITU-R P.837-7</option> + <option value='manual' aria-label="manual-entry">Specific Rain</option> + </select>} <div style={{ fontSize: 12, color: 'red' }}>{this.state.rainMethodError}</div> + </div> + </div> + <div> + <div>Rainfall Rate</div> <div> {<form><input aria-label="rain-value" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { this.props.updateRainValue(Number(e.target.value)) }} - value={this.props.rainVal} disabled={this.state.rainMethodDisplay === false ? true : false}> - </input> mm/hr {this.state.showWM} {this.props.month}</form> } </div> - <div aria-label="rain-attenuation-value">{this.props.rainAtt.toFixed(3)} dB</div> - - <div> {<select aria-label="select-absorption-method" className={this.state.attenuationMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => { if (e.target.value!== ''){ this.setState({absorptionMethod : e.target.value}); this.setState({attenuationMethodError:''}) }}}> - <option value='0' aria-label="none-value" >Select Absorption Method</option> - <option value='ITURP67612' aria-label="iturp67612" >ITU-R P.676-12</option> - <option value='ITURP67611' aria-label="iturp67611" >ITU-R P.676-11</option> - <option value='ITURP67610' aria-label="iturp67610" >ITU-R P.676-10</option> - </select>} <div style={{fontSize:12,color:'red'}}>{this.state.attenuationMethodError}</div> - </div> - <div aria-label="absorption-oxygen-value">{this.props.absorptionOxygen.toFixed(3)} dB</div> - <div aria-label="absorption-water-value">{this.props.absorptionWater.toFixed(3)} dB</div> - <div>{<button aria-label="calculate-button" style={{color: '#222', fontFamily:'Arial', boxAlign: 'center', display:'inline-block', insetInlineStart: '20' , alignSelf:'center' }} - onClick = {(e) => this.buttonHandler()} >Calculate</button>} </div> + value={this.props.rainVal} disabled={this.state.rainMethodDisplay === false ? true : false}> + </input> mm/hr {this.state.showWM} {this.props.month}</form>} </div> + </div> + <div> + <div>Rain Loss</div> + <div aria-label="rain-attenuation-value">{this.props.rainAtt.toFixed(3)} dB</div> + </div> + <div> + <div>Absorption Model</div> + <div> {<select aria-label="select-absorption-method" className={this.state.attenuationMethodError.length > 0 ? 'error' : 'input'} onChange={(e) => { if (e.target.value !== '') { this.setState({ absorptionMethod: e.target.value }); this.setState({ attenuationMethodError: '' }) } }}> + <option value='0' aria-label="none-value" >Select Absorption Method</option> + <option value='ITURP67612' aria-label="iturp67612" >ITU-R P.676-12</option> + <option value='ITURP67611' aria-label="iturp67611" >ITU-R P.676-11</option> + <option value='ITURP67610' aria-label="iturp67610" >ITU-R P.676-10</option> + </select>} <div style={{ fontSize: 12, color: 'red' }}>{this.state.attenuationMethodError}</div> + </div> + </div> + <div> + <div>Oxygen Specific Attenuation</div> + <div aria-label="absorption-oxygen-value">{this.props.absorptionOxygen.toFixed(3)} dB</div> + </div> + <div> + <div>Water Vapor Specific Attenuation</div> + <div aria-label="absorption-water-value">{this.props.absorptionWater.toFixed(3)} dB</div> + </div> + <div> + <div>System Operating Margin</div> + <div aria-label="system-operating-margin">{this.props.systemOperatingMargin} dB</div> + </div> + <div> + <div>Radio Transmitted Power</div> + <div> {<form><input aria-label="site-a-transmitted-power" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => {if (e.target.value !== '') this.props.UpdateTxPower(e.target.value,null) }} + > + </input> dBm </form>} </div> + <div> {<form><input aria-label="site-b-transmitted-power" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { if (e.target.value !== '') this.props.UpdateTxPower(null,e.target.value) }} + > + </input> dBm </form>} </div> + </div> + <div> + <div>RF Receiver Sensitivity</div> + <div> {<form><input aria-label="site-a-receiver-sensitivity" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { if (e.target.value !== '') this.props.UpdateRxSensitivity(e.target.value, null) }} + > + </input> dBm </form>} </div> + <div> {<form><input aria-label="site-b-receiver-sensitivity" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { if (e.target.value !== '') this.props.UpdateRxSensitivity(null, e.target.value) }} + > + </input> dBm </form>} </div> + </div> + </div> + <div className='antennaContainer'> + <div> + <div></div> + <div className='antennaFont'>Antenna Settings</div> + </div> + <div> + <div>Antenna</div> + + <div> {<select aria-label="site-a-select-antenna" value={this.props.antennaA} style={{ width: 160, height: 22, fontSize: 13 }} className={this.state.antennaTypeError.length > 0 ? 'error' : 'input'} onChange={(e) => { if (e.target.value !== '') { this.props.UpdateAntenas(e.target.value, null); this.setState({ antennaTypeError: '' }) } }}> + <option value='0' aria-label="none-value" >Select Antenna</option> + {this.props.antennaList.map(antenna => <option value={antenna}>{antenna}</option>)} + </select>} <div style={{ fontSize: 12, color: 'red' }}>{this.state.antennaTypeError}</div> + </div> + <div> {<select aria-label="site-b-select-antenna" value={this.props.antennaB} style={{ width: 160, height: 22, fontSize: 13 }} className={this.state.antennaTypeError.length > 0 ? 'error' : 'input'} onChange={(e) => { if (e.target.value !== '') { this.props.UpdateAntenas(null, e.target.value); this.setState({ antennaTypeError: '' }) } }}> + <option value='0' aria-label="none-value" >Select Antenna</option> + {this.props.antennaList.map(antenna => <option value={antenna}>{antenna}</option>)} + </select>} <div style={{ fontSize: 12, color: 'red' }}>{this.state.antennaTypeError}</div> + </div> </div> + <div> + <div>EIRP</div> + <div aria-label="site-a-effective-isotropic-radiated-power">{this.props.eirpSiteA} dBm</div> + <div aria-label="site-b-effective-isotropic-radiated-power">{this.props.eirpSiteB} dBm</div> </div> - <div className= 'middlecolumn'> - <div >Site B</div> - {this.props.siteB.length>0 &&<div> {this.props.siteB}</div>} - <div aria-label="site-b-latitude-dms"> {this.props.lat2 && this.LatLonToDMS(this.props.lat2)}</div> - <div aria-label="site-b-longitude-dms">{this.props.lon2 && this.LatLonToDMS(this.props.lon2)}</div> - <div>0</div> - <div aria-label="site-b-asml">{this.props.amslB.toFixed(2)} m</div> - <div aria-label="site-b-antenna-asml">{this.props.aglB.toFixed(2)} m</div> - - </div> - + <div> + <div>Gain</div> + <div aria-label="site-a-antenna-gain" > {this.props.antennaGainList[this.props.antennaList.indexOf(this.props.antennaA)]} dBi</div> + <div aria-label="site-b-antenna-gain">{this.props.antennaGainList[this.props.antennaList.indexOf(this.props.antennaB)]} dBi</div> + </div> + <div> + <div></div> + <div>{<button aria-label="calculate-button" style={{ color: '#222', fontFamily: 'Arial', boxAlign: 'center', display: 'inline-block', insetInlineStart: '20', alignSelf: 'center' }} + onClick={(e) => this.buttonHandler()} >Calculate</button>} </div> + </div> </div> - + <ConnectionInfo /> - - - - </div> - ) - } - + + + </div> + + ) } +} + export default connect(mapProps, mapDispatch)(LinkCalculation); |