# goip32

A simple api for goip32

# Installation

    pip install goip32

# Usage

## CLI

```
usage: goip32 [-h] [-u USERNAME] [-p PASSWORD] [--host HOST] [-w TIME]
              [-W TIME] [-r NUM] [--retry-delay TIME] [--retry-all-errors]
              [-m TIMEOUT] [-k] [-L] [--max-redirs NUM] [-A UA] [-x PROXY]
              [-H HEADER] [-b COOKIE] [-B BROWSER]
              {status-summary,status-general,status-sim,status-callforward,send-sms,send-ussd,inbox,outbox,call-records,clean-inbox,clean-outbox,expect-inbox,expect-outbox} ...

A simple api for goip32

General:
  -h, --help            Show this help message and exit
  -u, --username USERNAME
                        Specify username for authentication, defaults to
                        $GOIP32_USER
  -p, --password PASSWORD
                        Specify password for authentication, defaults to
                        $GOIP32_PASS
  --host HOST           Specify host, defaults to $GOIP32_HOST

subcommands:
  {status-summary,status-general,status-sim,status-callforward,send-sms,send-ussd,inbox,outbox,call-records,clean-inbox,clean-outbox,expect-inbox,expect-outbox}
    status-summary      get summary of lines
    status-general      get general info about the system and call status
    status-sim          get info about gsm in json format
    status-callforward  get info about sim call forward for lines
    send-sms            send sms
    send-ussd           send ussd code
    inbox               get inbox
    outbox              get outbox
    call-records        get call records
    clean-inbox         remove messages from inbox
    clean-outbox        remove messages from outbox
    expect-inbox        return newly received message
    expect-outbox       return newly sent message

Request settings:
  -w, --wait TIME       Set waiting time for each request
  -W, --wait-random TIME
                        Set random waiting time for each request to be from 0
                        to TIME
  -r, --retry NUM       Set number of retries for failed request to NUM
  --retry-delay TIME    Set interval between each retry
  --retry-all-errors    Retry no matter the error
  -m, --timeout TIMEOUT
                        Set request timeout, if in TIME format it'll be set
                        for the whole request. If in TIME,TIME format first
                        TIME will specify connection timeout, the second read
                        timeout. If set to '-' timeout is disabled
  -k, --insecure        Ignore ssl errors
  -L, --location        Allow for redirections, can be dangerous if
                        credentials are passed in headers
  --max-redirs NUM      Set the maximum number of redirections to follow
  -A, --user-agent UA   Sets custom user agent
  -x, --proxy PROXY     Use the specified proxy, can be used multiple times.
                        If set to URL it'll be used for all protocols, if in
                        PROTOCOL URL format it'll be set only for given
                        protocol, if in URL URL format it'll be set only for
                        given path. If first character is '@' then proxies are
                        read from file
  -H, --header HEADER   Set curl style header, can be used multiple times e.g.
                        -H 'User: Admin' -H 'Pass: 12345', if first character
                        is '@' then headers are read from file e.g. -H @file
  -b, --cookie COOKIE   Set curl style cookie, can be used multiple times e.g.
                        -b 'auth=8f82ab' -b 'PHPSESSID=qw3r8an829', without
                        '=' character argument is read as a file
  -B, --browser BROWSER
                        Get cookies from specified browser e.g. -B firefox
```

The tool needs `host`, `username` and `password` arguments specified in it's arguments before the subcommand, or in `GOIP32_HOST`, `GOIP32_USER`, `GOIP32_PASS`.

```bash
goip32 --host 'http://192.168.1.8:80' --username admin --password admin inbox

export GOIP32_HOST='http://192.168.1.8:80'
export GOIP32_USER=admin
export GOIP32_PASS=admin
goip32 inbox
```

Additional options for requests also can be specified before the subcommand

```bash
goip32 --wait 0.1 -header 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0' inbox
```

### status-summary

```bash
goip32 status-summary
```

Prints summary of lines in json format

```json
{
  "13": {
    "lac": "",
    "call_count": "NO LIMIT",
    "volte": "",
    "nocall_t": "8726",
    "asr": "",
    "gsm_status": "Y",
    "line_state": "IDLE",
    "status_line": "N",
    "sim_remain": "NO LIMIT",
    "sms_login": "",
    "gsm_signal": "5",
    "module_title_gsm": "",
    "gsm_cur_oper": "COSMOTE",
    "gsm_cur_bst": "",
    "module_status": "Y",
    "gsm_sim": "Y",
    "module_title": "Click to shut down module",
    "rct": "2025-11-14 21:43:30",
    "module_status_gsm": "13",
    "callc": "0/0",
    "smb_login": "N",
    "acd": "",
    "sms_count": "NO LIMIT",
    "callt": ""
  },
  "7": {
    "lac": "",
    "call_count": "NO LIMIT",
    "volte": "",
    "nocall_t": "8726",
    "asr": "",
    "gsm_status": "Y",
    "line_state": "IDLE",
    "status_line": "N",
    "sim_remain": "NO LIMIT",
    "sms_login": "",
    "gsm_signal": "6",
    "module_title_gsm": "",
    "gsm_cur_oper": "COSMOTE",
    "gsm_cur_bst": "",
    "module_status": "Y",
    "gsm_sim": "Y",
    "module_title": "Click to shut down module",
    "rct": "2025-11-14 21:43:29",
    "module_status_gsm": "7",
    "callc": "0/0",
    "smb_login": "N",
    "acd": "",
    "sms_count": "NO LIMIT",
    "callt": ""
  },
  "15": {
    "lac": "",
    "call_count": "NO LIMIT",
    "volte": "",
    "nocall_t": "8726",
    "asr": "",
    "gsm_status": "Y",
    "line_state": "IDLE",
    "status_line": "N",
    "sim_remain": "NO LIMIT",
    "sms_login": "",
    "gsm_signal": "6",
    "module_title_gsm": "",
    "gsm_cur_oper": "COSMOTE",
    "gsm_cur_bst": "",
    "module_status": "Y",
    "gsm_sim": "Y",
    "module_title": "Click to shut down module",
    "rct": "2025-11-14 21:43:30",
    "module_status_gsm": "15",
    "callc": "0/0",
    "smb_login": "N",
    "acd": "",
    "sms_count": "NO LIMIT",
    "callt": ""
  },
  "5": {
    "lac": "",
    "call_count": "NO LIMIT",
    "volte": "",
    "nocall_t": "8726",
    "asr": "",
    "gsm_status": "Y",
    "line_state": "IDLE",
    "status_line": "N",
    "sim_remain": "NO LIMIT",
    "sms_login": "",
    "gsm_signal": "6",
    "module_title_gsm": "",
    "gsm_cur_oper": "COSMOTE",
    "gsm_cur_bst": "",
    "module_status": "Y",
    "gsm_sim": "Y",
    "module_title": "Click to shut down module",
    "rct": "2025-11-14 21:43:27",
    "module_status_gsm": "5",
    "callc": "0/0",
    "smb_login": "N",
    "acd": "",
    "sms_count": "NO LIMIT",
    "callt": ""
  }
}
```

### status-general

```bash
goip32 status-general
```

Prints general info about the system and call status in json format

```json
{
  "hardware": {
    "s/n": "32M2RXXXXXXXXXXX",
    "firmware": "GST1610-1.01-70-17-8\n",
    "model": "GoIPx32",
    "time": "2025-11-20 23:13:49"
  },
  "network": {
    "ip": "192.168.0.22",
    "mac": "39:4E:10:06:94:A0",
    "pc port": "192.168.8.1",
    "pppoe": "DISABLED",
    "gateway": "192.168.0.1",
    "dns": "192.168.0.1"
  },
  "call status": {
    "10": {
      "fw_to_pstn": "Y",
      "config_mode": "S",
      "digits": "",
      "sim_remain": "NO LIMIT",
      "server": "",
      "fw_to_voip": "Y",
      "gsm_status": "Y",
      "status_line": "N",
      "proxy": "",
      "sip_prefix": ""
    },
    "16": {
      "fw_to_pstn": "Y",
      "config_mode": "S",
      "digits": "",
      "sim_remain": "NO LIMIT",
      "server": "",
      "fw_to_voip": "Y",
      "gsm_status": "Y",
      "status_line": "N",
      "proxy": "",
      "sip_prefix": ""
    },
    "20": {
      "fw_to_pstn": "Y",
      "config_mode": "S",
      "digits": "",
      "sim_remain": "NO LIMIT",
      "server": "",
      "fw_to_voip": "Y",
      "gsm_status": "Y",
      "status_line": "N",
      "proxy": "",
      "sip_prefix": ""
    }
  }
}
```

### status-sim

```json
goip32 status-sim
```

Prints info about gsm in json format

```json
{
  "sim_enable": "Remote SIM: DISABLE",
  "gsm": {
    "19": {
      "gsm_module_ver": "M26FBXXXXXX_RSIM",
      "gsm_module": "M26",
      "gsm_gprs_attach": "Y",
      "gsm_status": "Y",
      "gsm_gprs_login": "Y",
      "gsm_cur_bst": "",
      "gsm_sim": "Y",
      "lac": "LAC:32B1,CELL ID:C8C0",
      "gsm_signal": "8",
      "gsm_bst": "AUTO",
      "sim_imsi": "2260XXXXXXXXXXX",
      "gsm_imei": "8644XXXXXXXXXXX",
      "gsm_number": "",
      "sim_iccid": "89400XXXXXXXXXXXXXXX",
      "module_status_gsm": "19",
      "module_status_gsm2": "19",
      "gsm_cur_oper": "COSMOTE"
    },
    "4": {
      "gsm_module_ver": "M26FBXXXXXX_RSIM",
      "gsm_module": "M26",
      "gsm_gprs_attach": "Y",
      "gsm_status": "Y",
      "gsm_gprs_login": "Y",
      "gsm_cur_bst": "",
      "gsm_sim": "Y",
      "lac": "LAC:32B1,CELL ID:C8E0",
      "gsm_signal": "6",
      "gsm_bst": "AUTO",
      "sim_imsi": "2260XXXXXXXXXXX",
      "gsm_imei": "8644XXXXXXXXXXX",
      "gsm_number": "",
      "sim_iccid": "89400XXXXXXXXXXXXXXX",
      "module_status_gsm": "4",
      "module_status_gsm2": "4",
      "gsm_cur_oper": "COSMOTE"
    },
    "20": {
      "gsm_module_ver": "M26FBXXXXXX_RSIM",
      "gsm_module": "M26",
      "gsm_gprs_attach": "Y",
      "gsm_status": "Y",
      "gsm_gprs_login": "Y",
      "gsm_cur_bst": "",
      "gsm_sim": "Y",
      "lac": "LAC:32B1,CELL ID:C8E0",
      "gsm_signal": "9",
      "gsm_bst": "AUTO",
      "sim_imsi": "2260XXXXXXXXXXX",
      "gsm_imei": "8644XXXXXXXXXXX",
      "gsm_number": "",
      "sim_iccid": "89400XXXXXXXXXXXXXXX",
      "module_status_gsm": "20",
      "module_status_gsm2": "20",
      "gsm_cur_oper": "COSMOTE"
    }
  }
}
```

### status-callforward

```json
goip32 status-callforward
```

Prints info about sim call forward for lines in json format

```json
{
  "5": {
    "cf_busy_status": "OFF",
    "cf_uncnd_status": "OFF",
    "cf_notreachable_status": "OFF",
    "module_status_ccfc": "5",
    "cf_noreply_status": "OFF"
  },
  "9": {
    "cf_busy_status": "OFF",
    "cf_uncnd_status": "OFF",
    "cf_notreachable_status": "OFF",
    "module_status_ccfc": "9",
    "cf_noreply_status": "OFF"
  },
  "15": {
    "cf_busy_status": "OFF",
    "cf_uncnd_status": "OFF",
    "cf_notreachable_status": "Not Set",
    "module_status_ccfc": "15",
    "cf_noreply_status": "OFF"
  },
  "6": {
    "cf_busy_status": "OFF",
    "cf_uncnd_status": "OFF",
    "cf_notreachable_status": "OFF",
    "module_status_ccfc": "6",
    "cf_noreply_status": "OFF"
  }
}
```

### send-sms

```bash
goip32 send-sms 0238718819 MESSAGE 1 8
```

Sends `MESSAGE` to `0238718819` from line `1` and `8`, adding `--no-ensure` disables waiting for status if the message was send.

If message fails to deliver errors are returned e.g.

```json
{
  "1": "38",
  "8": "38"
}
```

### send-ussd

```bash
goip32 send-ussd '#MSG#' 4 9
```

Send `#MSG#` code from line `4` and `9` and get the response (can be ignored by setting `--no-ensure` flag).

```json
{
  "4": "send, but provider not reply.",
  "9": "send, but provider not reply."
}
```

### inbox

```bash
goip32 inbox
```

Prints the inbox history in json format

```json
{
  "6": [],
  "7": [],
  "8": [
    {
      "date": "11-16 19:03:18",
      "number": "+40766XXXXXX",
      "msg": "Test"
    },
    {
      "date": "11-16 18:58:13",
      "number": "+40766XXXXXX",
      "msg": "Test 2"
    }
  ],
  "16": [
    {
      "date": "11-20 17:49:16",
      "number": "888 Casino",
      "msg": "some black friday offer"
    }
  ]
}
```

Get inbox for specific lines

```bash
goip32 inbox 2 8
```

### outbox

```bash
goip32 inbox
```

Prints the inbox history in json format

```json
{
  "15": [],
  "16": [],
  "17": [],
  "18": [
    {
      "date": "11-16 11:31:06",
      "number": "0766XXXXXX",
      "msg": "YYYYYYYYYYYYYYYYYYYYYY"
    }
  ],
  "19": [
    {
      "date": "11-16 11:31:06",
      "number": "0766XXXXXX",
      "msg": "YYYYYYYYYYYYYYYYYYYYYY"
    },
    {
      "date": "11-15 11:34:10",
      "number": "0766XXXXXX",
      "msg": "UUUUUUUUUUUUUUUUUUUUUUUUUU"
    }
  ]
}
```

Get outbox for specific lines

```bash
goip32 inbox 7 11
```

### call-records

```bash
goip32 call-records
```

Prints history of the call records in json format

```json
[
  {
    "id": "160XXXXXXX",
    "Recv Time": "0753XXXXXXX,
    "Caller No.": "0772XXXXXXX,
    "Callee No.": "1",
    "Line ID": "0",
    "Outbound No.": "0",
    "Duration": "0",
    "Outbound Time": "0",
    "Answer Time": "0",
    "End Time": "0",
    "Hangup Side": "GoIP",
    "Hangup Reason": "403 ip auth fail"
  },
  {
    "id": "1609XXXXXXX,
    "Recv Time": "0753XXXXXXX,
    "Caller No.": "0772XXXXXXX,
    "Callee No.": "1",
    "Line ID": "0",
    "Outbound No.": "0772XXXXXXX,
    "Duration": "129",
    "Outbound Time": "1609XXXXXXX,
    "Answer Time": "1609XXXXXXX,
    "End Time": "1609XXXXXXX,
    "Hangup Side": "Network",
    "Hangup Reason": "BYE"
  }
]
```

### clean-inbox

```bash
goip32 clean-inbox 1 4.0 4.1
```

Removes all records of line `1` from inbox, and 2 first records of line `4`

### clean-outbox

```bash
goip32 clean-inbox 2 5.8
```

Removes all records of line `2` from inbox, and 9th record of line `5`

### expect-inbox

```bash
goip32 expect-inbox
```

Waits for new messages and prints them, by default for 120s (can be changed with `--expect-timeout`)

```json
{"date":"11-21 00:36:44","number":"+407XXXXXXXX","msg":"MESSAGE","line":"7"}
```

Waits for lines `8` and `3`, with 360s timeout

```bash
goip32 expect-inbox --expect-timeout 360 8 3
```

### expect-outbox

```bash
goip32 expect-outbox
```

Waits for new messages and prints them, by default for 120s (can be changed with `--expect-timeout`)

```json
{"date":"11-21 00:41:16","number":"07XXXXXXXX","msg":"MESSAGE","line":"7"}
{"date":"11-21 00:41:16","number":"07XXXXXXXX","msg":"MESSAGE","line":"8"}
```

Waits for lines `3` and `5`, with 360s timeout

```bash
goip32 expect-outbox --expect-timeout 360 3 5
```

## Library

### Code

```python
from goip32 import Api, Error, RequestError, TimeoutError

goip = Api('http://127.0.0.1:19203','admin','admin')

try:
    # tries to send a message until it succeeds
    while goip.send_sms('07XXXXXXXX','MESSAGE',[1,4]) != {}:
        pass
except RequestError as e:
    print(repr(e))

# print newly arrived messages
expect = goip.expect_inbox()
while True:
    try:
        for i in expect.check():
            print(i)
    except Error as e:
        print(repr(e))
```

### Api

`Api` class provides methods for interacting with goip32 site, at it's initialization requires `host` url, `username` and `password`, it also accepts parameters for [treerequests](https://github.com/TUVIMEN/treerequests) session.

#### status_summary(self) -> dict

Gets summary of lines

#### status_general(self) -> dict

Gets general info about the system and call status

#### status_sim(self) -> dict

Gets info about gsm

#### status_callforward(self) -> dict

Gets info about sim call forward for lines

#### send_sms(self, number: str, msg: str, lines: List[int | str] = [], ensure: bool = True) -> dict

Sends `msg` to `number` using `lines`.

If `ensure` is True it waits for response about whether the message arrived. If so `{}` is returned, otherwise an error list is returned.

#### send_ussd(self, msg: str, lines: List[int | str] = [], ensure: bool = True) -> dict

Sends `msg` command using `lines`.

If `ensure` is True the response or errors are returned, otherwise `{}`.

#### inbox(self) -> dict

Gets the whole inbox for all lines

#### outbox(self) -> dict

Gets the whole outbox for all lines

#### call_records(self) -> List[dict]

Gets all call records

#### clean_inbox(self, line: int | str = -1, pos: int | str = -1) -> dict

Cleans the whole inbox.

If `line` is not `-1`, it applies only to set line. If `pos` also isn't `-1`, then it applies only to message in `line` at `pos` (starting from 0).

#### clean_outbox(self, line: int | str = -1, pos: int | str = -1) -> dict

Literal analog to `clean_inbox` for outbox.

#### expect_inbox(self) -> NewMsg

Returns initialized `NewMsg` object for inbox.

#### expect_outbox(self) -> NewMsg

Literal analog to `expect_inbox` for outbox.

### NewMsg

Holds context of previous messages and should only be initialized by `expect_inbox` or `expect_outbox`.

#### check(self, retries: int = 40, wait: int = 3) -> Iterator[dict]

Returns the newest messages received, trying `retries` amount of times and waiting `wait` seconds in between them.

If nothing new is received `TimeoutError` is raised.

### Exceptions

All exceptions raised by this library are derived from `Error`.

`RequestError` is raised for errors when handling requests.

`TimeoutError` is raised by `NewMsg.check` method.
