DEVSTATE CHANGE not updating hints for CUSTOM extensions

Good afternoon. I’m looking at setting up a “demo” installation. With that, I’d like to have some BLF’s do some realistic flashing/changing. For example:
Button blinks for RINGING
Button goes solid for INUSE
wait 10 sec
Button goes dark for IDLE

I’ve created some custom extensions and registered a phone’s BLF to them, but it’s only showing IDLE state. When I issue “devstate change Custom:xxxx RINGING” (or busy), it doesn’t do anything to the BLF. In “core show hints”, they’re showing UNAVAILABLE.

Now, keep in mind, these demo extensions are not registered - they’re soley created to make this demo work. But, they’re still showing on the BLF as registered/IDLE.

Tested on both Asterisk 11 and 13. Does anyone know what I might be doing wrong on this? Or better, have a better way to do it?


I have a “hints” context at the end of my dialplan:
exten => _10XXX,hint,Custom:${EXTEN}@hints
exten => _7XXXX,hint,Custom:${EXTEN}@hints

You should be able to set the device state like this:
same => n,Set(DEVICE_STATE(Custom:${ARG1}@hints)=RINGING)
same => n,Set(DEVICE_STATE(Custom:${ARG1}@hints)=INUSE)
same => n,Set(DEVICE_STATE(Custom:${ARG1}@hints)=NOT_INUSE)

On Cisco phones, the lamp shows green id it’s NOT_INUSE (and you have an extension or speed dial there). I don’t believe you need to have s subscription to make it work. For me, it was a syntax problem until I figured it out.

It might be helpful if you to post your dialplan.

I have posted the dialplan below, but its just the default creation that FREEPBX13 does for custom extensions. I already show hints (and that my test phones have subscribed to them).

Since the hints already exist, I’m assuming these lines (hints, below) in your example aren’t necessary to add to my dialplan (since they are essentially already there).
exten => _10XXX,hint,Custom:${EXTEN}@hints
exten => _7XXXX,hint,Custom:${EXTEN}@hints

Here’s the current status of one of those hints:
1011@ext-local : CUSTOM/1011&Custom:D State:Unavailable Presence:not_set Watchers 2

You’ll note the state remains Unavailable, and is ignoring my devstate commands, even though devstate shows “state changed to x” when I issue it.

Here’s one of the test custom extensions (1011):
exten => FM1011,1,Goto(1011,FM1011)

exten => 1011,1,GotoIf($[ “${DB(AMPUSER/1011/followme/ddial)}” = “EXTENSION” ]?ext-local,1011,1)
exten => 1011,n(FM1011),Macro(user-callerid,)
exten => 1011,n,Set(DIAL_OPTIONS=${DIAL_OPTIONS}I)
exten => 1011,n,Set(CONNECTEDLINE(num,i)=1011)
exten => 1011,n,Gosub(sub-presencestate-display,s,1(1011))
exten => 1011,n,Set(CONNECTEDLINE(name)=${DB(AMPUSER/1011/cidname)}${PRESENCESTATE_DISPLAY})
exten => 1011,n,Set(FM_DIALSTATUS=${EXTENSION_STATE(1011@ext-local)})
exten => 1011,n,Set(__EXTTOCALL=${EXTEN})
exten => 1011,n,Set(__PICKUPMARK=${EXTEN})
exten => 1011,n,Macro(blkvm-setifempty,)
exten => 1011,n,GotoIf($["${GOSUB_RETVAL}" = “TRUE”]?skipov)
exten => 1011,n,Macro(blkvm-set,reset)
exten => 1011,n,Set(__NODEST=)
exten => 1011,n(skipov),Set(RRNODEST=${NODEST})
exten => 1011,n(skipvmblk),Set(__NODEST=${EXTEN})
exten => 1011,n,GosubIf($[${DB_EXISTS(AMPUSER/1011/followme/changecid)} = 1 & “${DB(AMPUSER/1011/followme/changecid)}” != “default” & “${DB(AMPUSER/1011/followme/changecid)}” != “”]?sub-fmsetcid,s,1())
exten => 1011,n,Set(RecordMethod=Group)
exten => 1011,n(checkrecord),Gosub(sub-record-check,s,1(exten,1011,))
exten => 1011,n(skipsimple),Set(RingGroupMethod=ringallv2-prim)
exten => 1011,n,Set(_FMGRP=1011)
exten => 1011,n(DIALGRP),GotoIf($[("${DB(AMPUSER/1011/followme/grpconf)}"=“ENABLED”) | ("${FORCE_CONFIRM}"!="") ]?doconfirm)
exten => 1011,n,Macro(dial,$[ ${DB(AMPUSER/1011/followme/grptime)} + ${DB(AMPUSER/1011/followme/prering)} ],${DIAL_OPTIONS},${DB(AMPUSER/1011/followme/grplist)})
exten => 1011,n,Goto(nextstep)
exten => 1011,n(doconfirm),Macro(dial-confirm,$[ ${DB(AMPUSER/1011/followme/grptime)} + ${DB(AMPUSER/1011/followme/prering)} ],${DIAL_OPTIONS},${DB(AMPUSER/1011/followme/grplist)},1011)
exten => 1011,n(nextstep),Set(RingGroupMethod=)
exten => 1011,n,GotoIf($[“foo${RRNODEST}” != “foo”]?nodest)
exten => 1011,n,Set(__NODEST=)
exten => 1011,n,Set(__PICKUPMARK=)
exten => 1011,n,Macro(blkvm-clr,)
exten => 1011,n,Goto(ext-local,1011,dest)
exten => 1011,n(nodest),Noop(SKIPPING DEST, CALL CAME FROM Q/RG: ${RRNODEST})

Any thoughts on how to achieve this?

Basically I want these custom extensions to appear to change state (seemingly) randomly, so the phones with their BLF subscriptions will see the state changes and simulate activity.


I’d use a cron job that calls asterisk to update the device states for your extensions.

Check out the ‘devstate change’ command.

asterisk -rx ‘devstate change Custom:demo-groupvm-7305 RINGING’ will update that custom device to be ringing.

That’s exactly what I was planning to use - problem is, it wasn’t working for those custom extensions. If you look above, you’ll see it takes the command and responds with “extension x is now RINGING” (or whatever), but doesn’t actually update the BLF hints. And when you pull a status, it remains in an UNAVAILABLE state, regardless of what I tell it.

Any thoughts as to why? I’m thinking the registration of the phone takes priority over my setting of the devstate…

I don’t see where your have your ‘core show hints’ output.

Maybe it’s how you have your hint defined?

Here is an example from my PBX


Ah, sorry. Missed that - figured stating the state was enough:

Just issued these commands - you can see, they’re accepted…
*CLI> devstate change Custom:1012 RINGING
Changing 1012 to RINGING
*CLI> devstate change Custom:1011 INUSE
Changing 1011 to INUSE

But here’s the result…
1011@ext-local : CUSTOM/1011&Custom:D State:Unavailable Presence: Watchers 2
1013@ext-local : CUSTOM/1013&Custom:D State:Unavailable Presence: Watchers 2
1012@ext-local : CUSTOM/1012&Custom:D State:Unavailable Presence: Watchers 2

Here’s one of the phones that are “watching”:
1001@ext-local : SIP/1001&Custom:DND1 State:Idle Presence: Watchers 0

Can You paste the output of 'dialplan show 1011@ext-local ’ ?

*CLI> dialplan show 1011@ext-local
[ Context ‘ext-local’ created by ‘pbx_config’ ]
‘1011’ => hint: CUSTOM/1011&Custom:DND1011,CustomPresence:1011 [pbx_config]
1. Set(__RINGTIMER=${IF($["${DB(AMPUSER/1011/ringtimer)}" > “0”]?${DB(AMPUSER/1011/ringtimer)}:${RINGTIMER_DEFAULT})}) [pbx_config]
2. Macro(exten-vm,1011,1011,0,0,0) [pbx_config]
[dest] 3. Set(__PICKUPMARK=) [pbx_config]
4. Macro(vm,1011,${DIALSTATUS},${IVR_RETVM}) [pbx_config]
5. Goto(vmret,1) [pbx_config]

-= 1 extension (6 priorities) in 1 context. =-

Try changing the device state of that, Yor Custom/1011 looks to be invalid to me as as it should have a colon not a slash in the hint.

Well, that’s quite a bummer. Since that’s auto-generated by FPBX13, I obviously can’t edit those generated files (they’ll get wiped on the next reload).

Any thoughts where I could put them that could override? I’m assuming the extensions_custom.conf file - and I’m assuming since its loaded last, it overrides anything previously built. Is that correct?

As a side-note, here’s the hint entry for a SIP extension that is working properly - it also has the forward slash:
‘1001’ => hint: SIP/1001&Custom:DND1001,CustomPresence:1001 [pbx_config]
1. Set(__RINGTIMER=${IF($["${DB(AMPUSER/1001/ringtimer)}" > “0”]?${DB(AMPUSER/1001/ringtimer)}:${RINGTIMER_DEFAULT})}) [pbx_config]
2. Macro(exten-vm,1001,1001,0,0,0) [pbx_config]
[dest] 3. Set(__PICKUPMARK=) [pbx_config]
4. Macro(vm,1001,${DIALSTATUS},${IVR_RETVM}) [pbx_config]
5. Goto(vmret,1) [pbx_config]

The slash seems to be calling the appropriate driver (SIP/ CUSTOM/ etc).

Right, I want to say the slash is appropriate when dealing with a channel driver. It’s the Custom device state that doesn’t use it.

Were you able to update the other Devicestate of CustomPresence:1011 ?

Since you are using FreePBX I’d recommend asking on their forum at

1 Like

I opened a bug report and highlighted the possible deviation from the norm.


If you manually edit the DIAL string that FPBX populates, so it has a colon instead, DEVSTATE works perfectly. :slight_smile: Interestingly, it now isn’t dialable though, with the following error:
WARNING[14293][C-00000007]: app_dial.c:2353 dial_exec_full: Dial argument takes format (technology/resource)

So, its interesting to me that dialing requires “technology/resource”, but DevState requires “Custom:resource”.

I even thought I’d get tricky and put the following in for the dial string:

DevState still works, but dialing doesn’t. :frowning:

I wonder if there’s a way I can force calls attempted to the “custom:1011” to actually translate to the proper dialable format. Also, now that I’ve got DevState working, any ideas how I’d script it? I’m not sure how, from the linux command line, I would issue a command to asterisk. I can figure out how to write the script easy enough, and cron it on boot, but the devstate command only works while within the asterisk console, so I’m not sure how to have linux issue a command to asterisk.

1 Like

Well, the FPBX folks rejected this as not a bug. I was able to piece something together so I guess I’ll just have to give up on this one - they seemed to think it was working perfectly, but when asked, they wouldn’t give me any examples how I might be doing it wrong, they just told me I was. Ok then…

Hi Kris, can you let me know what exact change did you make? thanks
PS. Trying to do the same thing with you.

Here’s an example of the end result that worked:

devstate change Custom:1011 RINGING
devstate change Custom:1011 INUSE
devstate change Custom:1011 NOT_INUSE

Here’s the catch… These are fake extensions. I had to build them as custom extension types (not SIP). I also activated call forwarding for them to send them directly to VM when the button is pushed. Unfortunately, you also can’t push the BLF when it’s blinking (as, depending on the phone, it auto-inserts the call pickup code), which fails. But it works for busy and idle, so that was good enough our needs.