1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#           http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16"""Python module for Spectracom/Orolia GSG-6 GNSS simulator."""
17
18from acts.controllers import abstract_inst
19
20
21class GSG6Error(abstract_inst.SocketInstrumentError):
22    """GSG-6 Instrument Error Class."""
23
24
25class GSG6(abstract_inst.SocketInstrument):
26    """GSG-6 Class, inherted from abstract_inst SocketInstrument."""
27
28    def __init__(self, ip_addr, ip_port):
29        """Init method for GSG-6.
30
31        Args:
32            ip_addr: IP Address.
33                Type, str.
34            ip_port: TCPIP Port.
35                Type, str.
36        """
37        super(GSG6, self).__init__(ip_addr, ip_port)
38
39        self.idn = ''
40
41    def connect(self):
42        """Init and Connect to GSG-6."""
43        self._connect_socket()
44
45        self.get_idn()
46
47        infmsg = 'Connected to GSG-6, with ID: {}'.format(self.idn)
48        self._logger.debug(infmsg)
49
50    def close(self):
51        """Close GSG-6."""
52        self._close_socket()
53
54        self._logger.debug('Closed connection to GSG-6')
55
56    def get_idn(self):
57        """Get the Idenification of GSG-6.
58
59        Returns:
60            GSG-6 Identifier
61        """
62        self.idn = self._query('*IDN?')
63
64        return self.idn
65
66    def start_scenario(self, scenario=''):
67        """Start to run scenario.
68
69        Args:
70            scenario: Scenario to run.
71                Type, str.
72                Default, '', which will run current selected one.
73        """
74        if scenario:
75            cmd = 'SOUR:SCEN:LOAD ' + scenario
76            self._send(cmd)
77
78        self._send('SOUR:SCEN:CONT START')
79
80        if scenario:
81            infmsg = 'Started running scenario {}'.format(scenario)
82        else:
83            infmsg = 'Started running current scenario'
84
85        self._logger.debug(infmsg)
86
87    def stop_scenario(self):
88        """Stop the running scenario."""
89
90        self._send('SOUR:SCEN:CONT STOP')
91
92        self._logger.debug('Stopped running scenario')
93
94    def preset(self):
95        """Preset GSG-6 to default status."""
96        self._send('*RST')
97
98        self._logger.debug('Reset GSG-6')
99
100    def set_power(self, power_level):
101        """set GSG-6 transmit power on all bands.
102
103        Args:
104            power_level: transmit power level
105                Type, float.
106                Decimal, unit [dBm]
107
108        Raises:
109            GSG6Error: raise when power level is not in [-160, -65] range.
110        """
111        if not -160 <= power_level <= -65:
112            errmsg = ('"power_level" must be within [-160, -65], '
113                      'current input is {}').format(str(power_level))
114            raise GSG6Error(error=errmsg, command='set_power')
115
116        self._send(':SOUR:POW ' + str(round(power_level, 1)))
117
118        infmsg = 'Set GSG-6 transmit power to "{}"'.format(
119            round(power_level, 1))
120        self._logger.debug(infmsg)
121