Remove service auto-registration, add clear setup instructions (v2.0.8)
This commit is contained in:
@@ -1,90 +1,86 @@
|
|||||||
# SIP Voice Notifier Add-on
|
# SIP Voice Notifier Add-on
|
||||||
|
|
||||||
Complete Home Assistant add-on for sending voice notifications via SIP phone calls.
|
## Installation Complete!
|
||||||
|
|
||||||
**Everything included** — just install the add-on, no separate integration needed!
|
The add-on is running and listening on port 8099.
|
||||||
|
|
||||||
## Features
|
## Setup Service in Home Assistant
|
||||||
|
|
||||||
- 📞 Place SIP calls from Home Assistant
|
To use the add-on, add this to your `/config/configuration.yaml`:
|
||||||
- 🔊 Play audio from HTTP/HTTPS URLs (MP3, WAV, etc.)
|
|
||||||
- 🗣️ Text-to-speech support
|
|
||||||
- ⚡ One-step installation (add-on includes integration)
|
|
||||||
- 🔧 Configurable call duration
|
|
||||||
- 🐳 Container-persistent (survives restarts)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Method 1: Local Add-on (Development)
|
|
||||||
|
|
||||||
1. **Copy add-on folder:**
|
|
||||||
```bash
|
|
||||||
cp -r addon-sip-notifier-v2 /addons/local/sip-notifier
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Add local repository:**
|
|
||||||
- Settings → Add-ons → Add-on Store → ⋮ (menu) → Repositories
|
|
||||||
- Add: `file:///addons/local`
|
|
||||||
|
|
||||||
3. **Install from store:**
|
|
||||||
- Find "SIP Voice Notifier" in local add-ons
|
|
||||||
- Click Install
|
|
||||||
|
|
||||||
### Method 2: GitHub Repository (Production)
|
|
||||||
|
|
||||||
1. **Create GitHub repo** with structure:
|
|
||||||
```
|
|
||||||
ha-sip-notifier/
|
|
||||||
├── repository.yaml
|
|
||||||
└── sip-notifier/
|
|
||||||
├── config.yaml
|
|
||||||
├── Dockerfile
|
|
||||||
├── services.yaml
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Add repository to Home Assistant:**
|
|
||||||
- Settings → Add-ons → Add-on Store → ⋮ → Repositories
|
|
||||||
- Add your GitHub URL
|
|
||||||
|
|
||||||
3. **Install from store**
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Settings → Add-ons → SIP Voice Notifier → Configuration
|
|
||||||
|
|
||||||
### Twilio Example
|
|
||||||
```yaml
|
```yaml
|
||||||
sip_server: "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pstn.twilio.com"
|
# SIP Voice Notifier Service
|
||||||
sip_user: "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
script:
|
||||||
sip_password: "your_auth_token"
|
sip_send_notification:
|
||||||
default_duration: 30
|
alias: "SIP Voice Notification"
|
||||||
|
description: "Send voice notification via SIP call"
|
||||||
|
icon: mdi:phone-voip
|
||||||
|
mode: queued
|
||||||
|
fields:
|
||||||
|
destination:
|
||||||
|
name: Destination
|
||||||
|
description: "Phone number (e.g., +15551234567)"
|
||||||
|
required: true
|
||||||
|
example: "+15551234567"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
audio_url:
|
||||||
|
name: Audio URL
|
||||||
|
description: "HTTP(S) URL to audio file (MP3/WAV)"
|
||||||
|
required: false
|
||||||
|
example: "https://example.com/alert.mp3"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
message:
|
||||||
|
name: Message
|
||||||
|
description: "Text message for TTS"
|
||||||
|
required: false
|
||||||
|
example: "Emergency alert message"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
duration:
|
||||||
|
name: Duration
|
||||||
|
description: "Call duration in seconds"
|
||||||
|
required: false
|
||||||
|
default: 30
|
||||||
|
example: 30
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 5
|
||||||
|
max: 300
|
||||||
|
sequence:
|
||||||
|
- service: rest_command.sip_notification_call
|
||||||
|
data:
|
||||||
|
destination: "{{ destination }}"
|
||||||
|
audio_url: "{{ audio_url | default('') }}"
|
||||||
|
message: "{{ message | default('') }}"
|
||||||
|
duration: "{{ duration | default(30) }}"
|
||||||
|
|
||||||
|
rest_command:
|
||||||
|
sip_notification_call:
|
||||||
|
url: "http://088d3b92-sip-notifier:8099/send_notification"
|
||||||
|
method: POST
|
||||||
|
content_type: "application/json"
|
||||||
|
payload: >
|
||||||
|
{
|
||||||
|
"destination": "{{ destination }}",
|
||||||
|
{% if audio_url and audio_url != '' %}"audio_url": "{{ audio_url }}",{% endif %}
|
||||||
|
{% if message and message != '' %}"message": "{{ message }}",{% endif %}
|
||||||
|
"duration": {{ duration | default(30) }}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### VoIP.ms Example
|
## Restart Home Assistant
|
||||||
```yaml
|
|
||||||
sip_server: "yourserver.voip.ms"
|
|
||||||
sip_user: "123456_subaccount"
|
|
||||||
sip_password: "your_password"
|
|
||||||
default_duration: 30
|
|
||||||
```
|
|
||||||
|
|
||||||
### Generic SIP Provider
|
After adding to configuration.yaml:
|
||||||
```yaml
|
- Settings → System → Restart
|
||||||
sip_server: "sip.example.com"
|
|
||||||
sip_user: "username"
|
|
||||||
sip_password: "password"
|
|
||||||
default_duration: 30
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Once the add-on is running, the service `sip_notifier.send_notification` is automatically available in Home Assistant!
|
|
||||||
|
|
||||||
### Play Audio from URL
|
### Play Audio from URL
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service: sip_notifier.send_notification
|
service: script.sip_send_notification
|
||||||
data:
|
data:
|
||||||
destination: "+15551234567"
|
destination: "+15551234567"
|
||||||
audio_url: "https://example.com/alert.mp3"
|
audio_url: "https://example.com/alert.mp3"
|
||||||
@@ -94,168 +90,73 @@ data:
|
|||||||
### Text-to-Speech
|
### Text-to-Speech
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service: sip_notifier.send_notification
|
service: script.sip_send_notification
|
||||||
data:
|
data:
|
||||||
destination: "+15551234567"
|
destination: "+15551234567"
|
||||||
message: "This is a voice notification from Home Assistant"
|
message: "Emergency! Water leak detected!"
|
||||||
duration: 20
|
duration: 40
|
||||||
```
|
```
|
||||||
|
|
||||||
### Service Parameters
|
## Example Automation
|
||||||
|
|
||||||
| Parameter | Required | Description |
|
|
||||||
|-----------|----------|-------------|
|
|
||||||
| `destination` | Yes | Phone number (+1...) or SIP URI |
|
|
||||||
| `audio_url` | No* | HTTP(S) URL to audio file |
|
|
||||||
| `message` | No* | Text message for TTS |
|
|
||||||
| `duration` | No | Call duration in seconds (default: 30) |
|
|
||||||
|
|
||||||
\* Either `audio_url` or `message` required
|
|
||||||
|
|
||||||
## Example Automations
|
|
||||||
|
|
||||||
### Water Leak Emergency
|
|
||||||
```yaml
|
```yaml
|
||||||
automation:
|
automation:
|
||||||
- alias: "Water Leak Alert"
|
- alias: "Water Leak Emergency Call"
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
platform: state
|
||||||
entity_id: binary_sensor.water_leak
|
entity_id: binary_sensor.water_leak
|
||||||
to: "on"
|
to: "on"
|
||||||
action:
|
action:
|
||||||
- service: sip_notifier.send_notification
|
- service: script.sip_send_notification
|
||||||
data:
|
data:
|
||||||
destination: "+15551234567"
|
destination: "+15551234567"
|
||||||
message: "EMERGENCY! Water leak detected!"
|
message: "EMERGENCY! Water leak detected in basement!"
|
||||||
duration: 40
|
duration: 45
|
||||||
```
|
```
|
||||||
|
|
||||||
### Doorbell Notification
|
|
||||||
```yaml
|
|
||||||
automation:
|
|
||||||
- alias: "Doorbell Call"
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: binary_sensor.doorbell
|
|
||||||
to: "on"
|
|
||||||
action:
|
|
||||||
- service: sip_notifier.send_notification
|
|
||||||
data:
|
|
||||||
destination: "+15551234567"
|
|
||||||
audio_url: "https://yourdomain.com/doorbell.mp3"
|
|
||||||
duration: 15
|
|
||||||
```
|
|
||||||
|
|
||||||
### Motion Detection (Armed Only)
|
|
||||||
```yaml
|
|
||||||
automation:
|
|
||||||
- alias: "Security Motion Alert"
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: binary_sensor.motion
|
|
||||||
to: "on"
|
|
||||||
condition:
|
|
||||||
- condition: state
|
|
||||||
entity_id: alarm_control_panel.home
|
|
||||||
state: "armed_away"
|
|
||||||
action:
|
|
||||||
- service: sip_notifier.send_notification
|
|
||||||
data:
|
|
||||||
destination: "+15551234567"
|
|
||||||
message: "Motion detected in your home!"
|
|
||||||
duration: 25
|
|
||||||
```
|
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
1. **Add-on** runs in dedicated container with PJSIP, ffmpeg, etc.
|
|
||||||
2. **Supervisor** auto-registers `sip_notifier.send_notification` service
|
|
||||||
3. **Service call** triggers add-on endpoint
|
|
||||||
4. **Add-on** downloads/converts audio and places SIP call
|
|
||||||
5. **No separate integration needed!**
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Add-on won't start
|
### Service not found
|
||||||
|
|
||||||
**Check logs:** Settings → Add-ons → SIP Voice Notifier → Log
|
1. Check you added the script to configuration.yaml
|
||||||
|
2. Restart Home Assistant
|
||||||
Common issues:
|
3. Check for syntax errors in configuration.yaml
|
||||||
- Invalid SIP credentials
|
|
||||||
- SIP server unreachable
|
|
||||||
- Configuration missing required fields
|
|
||||||
|
|
||||||
### Service not available
|
|
||||||
|
|
||||||
- Ensure add-on is running
|
|
||||||
- Restart Home Assistant
|
|
||||||
- Check add-on has `homeassistant_api: true` in config
|
|
||||||
|
|
||||||
### Call fails
|
### Call fails
|
||||||
|
|
||||||
- Check add-on logs for detailed SIP errors
|
Check add-on logs:
|
||||||
- Verify phone number format (+15551234567)
|
Settings → Add-ons → SIP Voice Notifier → Log
|
||||||
- Test SIP credentials with your provider
|
|
||||||
- Ensure firewall allows UDP port 5060
|
|
||||||
|
|
||||||
### No audio
|
Common issues:
|
||||||
|
- Incorrect SIP credentials
|
||||||
|
- Phone number format (use international: +1...)
|
||||||
|
- Network connectivity to SIP server
|
||||||
|
|
||||||
- Check audio URL is publicly accessible
|
## Configuration
|
||||||
- Test with TTS first (`message:` instead of `audio_url:`)
|
|
||||||
- Look for conversion errors in add-on logs
|
|
||||||
- Ensure audio format is compatible (MP3/WAV recommended)
|
|
||||||
|
|
||||||
## Audio Format Support
|
Add-on configuration options:
|
||||||
|
|
||||||
- **Input:** MP3, WAV, OGG, FLAC, etc. (via pydub)
|
- **sip_server**: Your SIP provider's server address
|
||||||
- **Output:** Automatically converted to 8kHz mono WAV
|
- **sip_user**: Your SIP username
|
||||||
- **Best performance:** Use 8-16kHz mono WAV to skip conversion
|
- **sip_password**: Your SIP password
|
||||||
|
- **default_duration**: Default call duration in seconds (5-300)
|
||||||
|
|
||||||
## SIP Provider Recommendations
|
## SIP Providers
|
||||||
|
|
||||||
| Provider | Cost/min | Quality | Setup |
|
### Twilio
|
||||||
|----------|----------|---------|-------|
|
```yaml
|
||||||
| Twilio | $0.013 | Excellent | Easy |
|
sip_server: "ACXXXXX.pstn.twilio.com"
|
||||||
| VoIP.ms | $0.009 | Very Good | Easy |
|
sip_user: "ACXXXXX"
|
||||||
| Vonage | Varies | Good | Medium |
|
sip_password: "your_auth_token"
|
||||||
| Bandwidth | $0.006 | Good | Medium |
|
```
|
||||||
|
|
||||||
## Security
|
### VoIP.ms
|
||||||
|
```yaml
|
||||||
- Add-on runs in isolated container
|
sip_server: "server.voip.ms"
|
||||||
- SIP credentials stored in encrypted HA config
|
sip_user: "123456_subaccount"
|
||||||
- API only accessible within Home Assistant network
|
sip_password: "password"
|
||||||
- No external dependencies besides SIP provider
|
```
|
||||||
|
|
||||||
## Performance
|
|
||||||
|
|
||||||
- **Startup:** 2-5 seconds
|
|
||||||
- **Call setup:** 3-5 seconds
|
|
||||||
- **Memory:** 50-80 MB
|
|
||||||
- **CPU:** Low (spike during audio conversion)
|
|
||||||
|
|
||||||
## Supported Architectures
|
|
||||||
|
|
||||||
- aarch64 (Raspberry Pi 3/4/5, 64-bit)
|
|
||||||
- amd64 (Intel/AMD 64-bit)
|
|
||||||
- armhf (Raspberry Pi 2/3, 32-bit)
|
|
||||||
- armv7 (ARM 32-bit)
|
|
||||||
- i386 (Intel/AMD 32-bit)
|
|
||||||
|
|
||||||
## What's Different from v1?
|
|
||||||
|
|
||||||
**v1:** Add-on + separate custom integration
|
|
||||||
**v2:** Add-on only (integration built-in)
|
|
||||||
|
|
||||||
Simpler installation — just one component!
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Check add-on logs first:
|
Issues: https://git.aymerick.fr/Aymerick/ha-sip-notifier/issues
|
||||||
Settings → Add-ons → SIP Voice Notifier → Log
|
|
||||||
|
|
||||||
Enable debug logging by restarting the add-on with "Show in sidebar" enabled.
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: "SIP Voice Notifier"
|
name: "SIP Voice Notifier"
|
||||||
version: "2.0.7"
|
version: "2.0.8"
|
||||||
slug: "sip-notifier"
|
slug: "sip-notifier"
|
||||||
description: "Send voice notifications via SIP phone calls"
|
description: "Send voice notifications via SIP phone calls"
|
||||||
arch:
|
arch:
|
||||||
|
|||||||
@@ -24,44 +24,6 @@ app = Flask(__name__)
|
|||||||
# Global config
|
# Global config
|
||||||
CONFIG = {}
|
CONFIG = {}
|
||||||
DEFAULT_SAMPLE_RATE = 8000
|
DEFAULT_SAMPLE_RATE = 8000
|
||||||
SUPERVISOR_TOKEN = os.environ.get('SUPERVISOR_TOKEN')
|
|
||||||
|
|
||||||
|
|
||||||
def register_service():
|
|
||||||
"""Register service with Home Assistant via Supervisor."""
|
|
||||||
if not SUPERVISOR_TOKEN:
|
|
||||||
_LOGGER.warning("No SUPERVISOR_TOKEN, skipping service registration")
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
headers = {
|
|
||||||
'Authorization': f'Bearer {SUPERVISOR_TOKEN}',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Register service via Supervisor API
|
|
||||||
response = requests.post(
|
|
||||||
'http://supervisor/services',
|
|
||||||
headers=headers,
|
|
||||||
json={
|
|
||||||
'domain': 'sip_notifier',
|
|
||||||
'service': 'send_notification',
|
|
||||||
'addon': '088d3b92_sip-notifier'
|
|
||||||
},
|
|
||||||
timeout=10
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.status_code in [200, 201]:
|
|
||||||
_LOGGER.info("✅ Service registered: sip_notifier.send_notification")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
_LOGGER.warning(f"Service registration status: {response.status_code}")
|
|
||||||
_LOGGER.debug(f"Response: {response.text}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
_LOGGER.error(f"Failed to register service: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def download_and_convert_audio(url: str) -> str:
|
def download_and_convert_audio(url: str) -> str:
|
||||||
@@ -265,16 +227,15 @@ if __name__ == '__main__':
|
|||||||
'default_duration': int(os.getenv('DEFAULT_DURATION', 30))
|
'default_duration': int(os.getenv('DEFAULT_DURATION', 30))
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register service with Home Assistant
|
_LOGGER.info("=" * 60)
|
||||||
_LOGGER.info("Registering service with Home Assistant...")
|
_LOGGER.info("SIP Voice Notifier Add-on Ready")
|
||||||
time.sleep(2) # Wait for supervisor to be ready
|
_LOGGER.info("=" * 60)
|
||||||
|
_LOGGER.info("Using pyVoIP from git (latest version)")
|
||||||
if register_service():
|
_LOGGER.info(f"SIP Server: {CONFIG.get('sip_server', 'not configured')}")
|
||||||
_LOGGER.info("Service registration successful")
|
_LOGGER.info(f"SIP User: {CONFIG.get('sip_user', 'not configured')}")
|
||||||
else:
|
_LOGGER.info("")
|
||||||
_LOGGER.warning("Service registration failed - will be available via REST API on port 8099")
|
_LOGGER.info("To use this add-on, add configuration to configuration.yaml")
|
||||||
|
_LOGGER.info("See add-on README for details")
|
||||||
_LOGGER.info("SIP Voice Notifier ready (using pyVoIP from git)")
|
_LOGGER.info("=" * 60)
|
||||||
_LOGGER.info("Service: sip_notifier.send_notification")
|
|
||||||
_LOGGER.info("Starting Flask service on port 8099")
|
_LOGGER.info("Starting Flask service on port 8099")
|
||||||
app.run(host='0.0.0.0', port=8099, debug=False)
|
app.run(host='0.0.0.0', port=8099, debug=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user