Files
claudetools/clients/valleywide/voip/DEVICE-ASSIGNMENT-COMMANDS.md
Mike Swanson db10206aea feat(voip): VWP complete provisioning prep + setup documentation
Critical RPS provisioning URL fix + CSV bulk import ready + complete VoIP setup guide

CRITICAL FIX:
- RPS server URL corrected: http://ndp.ucaasnetwork.com/cfg (was ftp://p.packetdials.net)
- Discovered ACG has TWO whitelabel accounts (WLC vs OIT/PacketDial)
- Test phone (805e0cdd71b1) now registered immediately after fix (Status 1)

USER PROVISIONING:
- M365 account matching: 11 matched users, 7 unmatched (need clarification)
- CSV bulk import prepared (vwp-users-import.csv)
- Strategy: users WITHOUT devices initially (add phone extension: no)
- Device assignment workflow: incremental as phones distributed

COMPLETE VOIP SETUP DOCUMENTED:
- DID (phone number) management + routing options
- Call queues (ring groups) - recommended queues for VWP
- Auto-attendants (IVR menus) - main menu design
- Time frames (business hours routing)
- Additional features (hunt groups, voicemail-only, fax-to-email)
- All components with API commands + examples

FILES CREATED (7):
- README.md: Quick navigation hub + domain info
- PROVISIONING-STATUS.md: Current status + next steps
- SESSION-SUMMARY-2026-07-09.md: Complete session documentation (18 pages)
- COMPLETE-CLIENT-SETUP.md: Full VoIP setup guide (15 pages)
- DEVICE-ASSIGNMENT-COMMANDS.md: Copy-paste command reference
- extension-mapping.md: Extension to M365 account mapping
- vwp-users-import.csv: Bulk import file (READY for upload)

IMPLEMENTATION PHASES:
Phase 1 (In Progress): Basic connectivity - CSV ready for upload
Phase 2 (Planned): Main line setup - queue + auto-attendant + DID
Phase 3 (Planned): Business hours routing - time-based call handling
Phase 4 (Optional): Additional features per client needs

NEXT ACTIONS:
- Upload CSV to PacketDial web UI (manual step)
- Get client clarification on 7 unmatched users
- Assign devices as phones distributed (per-phone workflow documented)

Domain: vwp.91912.service
Main Number: 480-705-9500
E911: a-6a395c03d4cfe (301 N 56TH ST, CHANDLER AZ)
YMCS Site: 1e7578a6fe0e41cfb5a3e8b40933ffee

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-07-09 20:21:57 -07:00

8.0 KiB

VWP Device Assignment - Quick Command Reference

Domain: vwp.91912.service YMCS Site ID: 1e7578a6fe0e41cfb5a3e8b40933ffee

Use this as a copy-paste reference when assigning phones to users.


Per-Phone Workflow (When User Provides MAC Last 4)

Replace {EXT}, {NAME}, {EMAIL}, {LAST4}, {DEVICE-ID}, {ACCOUNT-ID}, {SIP-PASSWORD} with actual values.

Step 1: Create SIP Device in PacketDial

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  create-device vwp.91912.service {EXT} --body '{
    "device": "{EXT}a@vwp.91912.service"
  }' --confirm

Example (Extension 102):

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  create-device vwp.91912.service 102 --body '{
    "device": "102a@vwp.91912.service"
  }' --confirm

Step 2: Get Auto-Generated SIP Password

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  devices vwp.91912.service {EXT} | python3 -c "import sys, json; d=json.load(sys.stdin); print(d[0].get('device-sip-registration-password'))"

Example (Extension 102):

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  devices vwp.91912.service 102 | python3 -c "import sys, json; d=json.load(sys.stdin); print(d[0].get('device-sip-registration-password'))"

Save the password - you'll need it in the next step.


Step 3: Create YMCS SIP Account

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  add-sipaccount --body '{
    "registerName": "{EXT}@vwp.91912.service",
    "username": "{EXT}@vwp.91912.service",
    "password": "{SIP-PASSWORD}",
    "label": "Ext {EXT} - {NAME}",
    "displayName": "{NAME}",
    "sipServer1": {
      "host": "pbx.packetdial.com",
      "port": 5060
    },
    "remark": "Valley Wide Plastering - {EMAIL}",
    "siteId": "1e7578a6fe0e41cfb5a3e8b40933ffee"
  }' --confirm

Example (Extension 102 - Jesse Guerrero):

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  add-sipaccount --body '{
    "registerName": "102@vwp.91912.service",
    "username": "102@vwp.91912.service",
    "password": "ySjl5J2Tiv2FBT6M",
    "label": "Ext 102 - Jesse Guerrero",
    "displayName": "Jesse Guerrero",
    "sipServer1": {
      "host": "pbx.packetdial.com",
      "port": 5060
    },
    "remark": "Valley Wide Plastering - jesse@valleywideplastering.com",
    "siteId": "1e7578a6fe0e41cfb5a3e8b40933ffee"
  }' --confirm

Save the account ID from the response - you'll need it in Step 5.


Step 4: Find Physical Phone by Last 4 of MAC

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py devices | grep -i "{LAST4}"

Example (MAC ending in 71b1):

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py devices | grep -i "71b1"

Extract the device ID from the output (the "id" field).


Step 5: Bind SIP Account to Physical Phone

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  raw POST /v2/dm/devices/{DEVICE-ID}/bindAccounts --body '[{
    "lineId": 1,
    "accountType": 0,
    "accountId": "{ACCOUNT-ID}"
  }]' --confirm

Example:

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  raw POST /v2/dm/devices/c8d9e0f1a2b3c4d5/bindAccounts --body '[{
    "lineId": 1,
    "accountType": 0,
    "accountId": "a1b2c3d4e5f6g7h8"
  }]' --confirm

Step 6: Reboot Phone

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  reboot --body '{
    "deviceIds": ["{DEVICE-ID}"],
    "deviceType": 1
  }' --confirm

Example:

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  reboot --body '{
    "deviceIds": ["c8d9e0f1a2b3c4d5"],
    "deviceType": 1
  }' --confirm

Step 7: Verify Registration

Check in PacketDial:

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  devices vwp.91912.service {EXT}

Look for:

  • device-sip-registration-state: "registered" (success)
  • device-sip-registration-contact: Shows phone IP/port
  • device-sip-registration-datetime: Recent timestamp

Check in YMCS:

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  raw GET /v2/dm/devices/{DEVICE-ID}

Look for:

  • accounts[].status: 1 = Registered ✓

All 11 Users - Reference Data

Copy-paste reference for each user when their phone is distributed:

Extension 102 - Jesse Guerrero

Extension: 102
Name: Jesse Guerrero
Email: jesse@valleywideplastering.com

Extension 103 - Rose Guerrero

Extension: 103
Name: Rose Guerrero
Email: rose@valleywideplastering.com

Extension 104 - Shelly Dooley

Extension: 104
Name: Shelly Dooley
Email: shelly@valleywideplastering.com

Extension 105 - JR Guerrero

Extension: 105
Name: JR Guerrero
Email: j-r@valleywideplastering.com

Extension 107 - Payroll Department

Extension: 107
Name: Payroll Department
Email: payroll@valleywideplastering.com

Extension 109 - Kayla Guerrero

Extension: 109
Name: Kayla Guerrero
Email: kayla@valleywideplastering.com

Extension 110 - Ron Winger

Extension: 110
Name: Ron Winger
Email: ron@valleywideplastering.com

Extension 113 - Chris Guerrero

Extension: 113
Name: Chris Guerrero
Email: chris@valleywideplastering.com

Extension 114 - Ty Fetters

Extension: 114
Name: Ty Fetters
Email: Ty@CASARICA.NET

Extension 115 - Toni Billing

Extension: 115
Name: Toni Billing
Email: billing@valleywideplastering.onmicrosoft.com

Extension 116 - Bart Graffin

Extension: 116
Name: Bart Graffin
Email: estimating@valleywideplastering.com

Troubleshooting

Phone Shows Status 3 (Unregistered)

Check password:

bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
  devices vwp.91912.service {EXT}
# Compare device-sip-registration-password with YMCS account password

Update YMCS account if password mismatch:

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  raw PATCH /v2/dm/sipAccounts/{ACCOUNT-ID} --body '{
    "registerName": "{EXT}@vwp.91912.service",
    "username": "{EXT}@vwp.91912.service",
    "password": "{CORRECT-PASSWORD}",
    "sipServer1": {"host": "pbx.packetdial.com", "port": 5060}
  }' --confirm

Account Already Exists (HTTP 400 / 800003)

Use PATCH instead of POST in Step 3:

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py \
  raw PATCH /v2/dm/sipAccounts/{ACCOUNT-ID} --body '{...}' --confirm

Phone Not Pulling Config

  1. Check binding: ymcs.py raw GET /v2/dm/devices/{DEVICE-ID}/boundAccounts
  2. Reboot phone manually or via ymcs.py reboot
  3. Check firewall - phone needs HTTPS to us-api.ymcs.yealink.com

Bulk Operations (If Doing Multiple Phones)

Get All Device IDs at Once

bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py devices | \
  python3 -c "import sys, json; [print(f\"{d.get('mac','')[-4:]}: {d.get('id')}\") for d in json.load(sys.stdin)]"

Check Registration Status for All VWP Users

for ext in 102 103 104 105 107 109 110 113 114 115 116; do
  echo -n "Extension $ext: "
  bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py \
    devices vwp.91912.service $ext 2>/dev/null | \
    python3 -c "import sys, json; d=json.load(sys.stdin); print(d[0].get('device-sip-registration-state', 'no device') if d else 'no device')"
done

Constants (For Reference)

# Domain
DOMAIN="vwp.91912.service"

# YMCS Site ID
SITE_ID="1e7578a6fe0e41cfb5a3e8b40933ffee"

# SIP Server
SIP_HOST="pbx.packetdial.com"
SIP_PORT="5060"

# PacketDial Script
NS_PY="bash .claude/scripts/py.sh .claude/skills/packetdial/scripts/ns.py"

# YMCS Script
YMCS_PY="bash .claude/scripts/py.sh .claude/skills/yealink-ymcs/scripts/ymcs.py"

Last Updated: 2026-07-09 Status: Ready for use after CSV import completes