We have a customer who is using a new Asterisk phone system we set up for them using SPA504Gs and SPA500DS sidecars. They want to mimic their old system, where once a call is picked up on an extension it can be placed on hold and picked up from anywhere without having to actively transfer it to a single phone.
For instance, person A picks up Line 1. Person A pages all the phones to say there is a call available on Line 1 for Person B. Person B needs to be able to pick that call up wherever they are.
We currently have the SPA504G's set up where Line 1 is the inbound extension, and Lines2-4 represent the DID's for the customer. When a call is picked up off one of the DIDs it is only active on that phone, so that other callers could call into the DID.
We're unclear how to make it so the call can be picked up from anywhere, could be make a 'Parked Call' key on the sidecar that could old these calls somehow? Is there an easier way that would actively mimic their old PBX more directly (where 'Line 1' was actually 'Line 1' everywhere).
That feature called call parking and it already present in most asterisk system
Or maybe you are reffering to call pickup(*8) - if so you have put same pickupgroup on all extensions.
Unfortanly no way say which system you have and how to enable it on your system.
Related
is there any easy way to detect that agent stopped on a roller conveyor because there are other agents ahead? I tried to use dynamic variable and conditional event but it is consuming too much performence. I donĀ“t want to go for dynamically checking condition (with cyclic event) because I have some bad experience with it.
Thanks!
Try this:
Create a LinkedList<YourAgentType> agentsOnConveyor.
Whenever an agent enters the conveyor, call agentsOnConveyor.addLast(agent). When it leaves, call agentsOnConveyor.removeFirst(agent).
Now you have a linked representation of the agents on the conveyor.
Last, you use the "on stopped" field in the conveyor and pass the message "upstream" through the linked list, i.e. use a for-loop from the first to the last entry and send them a msg "conveyor stopped".
You may still need to check if the individual agent is moving itself or has also stopped, but it might put you on a working path
I have 2 storages (called storageA & storageB) and I want to move an agent (pallet) from one to the other via forklifts. I have set up the following.
A pallet is created at a node and is moved to storageA via 'store'. This part works fine. The pallet is then moved to storageB via 'store1' after a delay. This is when the following error occurs:
Exception during discrete event execution:
root.store1.seizeTrans.freeSpaceSendTo:
Path not found! {agent=2, source={level=level, pos=(1673.3333333333333, 3245.0, 0.0)}, target={level=level, pos=(1857.25, 3160.4845, 0.0)}}
It works if I replace 'store1' with a retrieve block and send it to a node first. However I would like to send the pallet directly to another storage rather than via another location. Is this possible?
Please let me know if I have not provided enough information.
Thanks
yeah unfortunately you can't do that as far as I know, the solution I use is the following, which is actually not a super robust solution... but has been ok in applications so far
Place a retrieve block between your delay and your store1
Use the agent you pick up as destination:
on the on seize action of the retrieve block do:agent.transporter=unit;
4.On the store1 block put the highest priority for the task
5. ON the store1 block use resource custom transporter choice: agent.transporter.equals(unit)
6. The dispatching policy should be nearest to the agent in store1, but doing all the above ensures that the resource continues doing the task no matter what... by only using the dispatch policy your model will work 99.999999% of the time... the problem occurs only if another task with higher priority occurs at the exact same time as the transporter is released in the retrieve block, which is rare, but can happen.
I had the same question today so I landed here. But luckily, only after the second step written above, the whole process needed did already work for my case. We can move an agent from one storage to another by simply set the destination of the 'retrieve' block to the coordinate of the agent and the move to independently instead of by fleets or resources. after that we put the 'store' block.
Destination is: (x,y,z)
X: agent.getX()
Y: agent.getY()
Z: agent.getZ()
after agents being retrieved to a specified coordinate, it seems that fleets do not comply paths in the network anymore
I am trying to force agents of a population to exchange messages in AnyLogic. I would like each time agent A sends a message to B the icon of the message to move from A to B. How can I implement this?
The code Emile sent you works to move an agent from one place to another one. I understand you don't want to move your two agents, but instead you want to move only a "message icon" from one to the other. For that you can create an agent (let's call it agent "Message"), create it and locate it in the agentA, and tell it (as Emile said) to move to agentB: messageAB.moveTo(agentB.getPosition()); this way you'll get the effect you want.
You could also:
use a timer to move from one place to another, or
use an event and change the position of the icon dinamically depending on how much time you have remaining on that event
use a source/delay/sink for the same as in point 2
There are basically two ways to move an agent:
Jump to agent B: Instantly appears near agent B
Move to agent A at a certain speed
For each one the code is respectively as follows:
agentA.jumpTo( agentB.getXYZ() );
agentA.moveTo( agentB );
Where agentA and agentB refer to the agents which you might call differently depending where you are in the model.
I would like to mix a serpentine line and a straight line queue system where the serpentine line has several service points. I would then like the strait line to use a particular service point of the serpentine lines service points... not the one created with it. Thanks in advance...
This is not possible by default.
A possible workaround: Use the servicePoints as they are in your screenshot right now, but suspend/reactivate the 2 uppermost servicePoints as needed whenever priority customers are present or not. The function to do this is this:
public void setServiceSuspended(ServiceUnit<Q> serviceUnit,
boolean suspended)
Implemenent checks to make sure both servicePoints cannot be active at the same time.
I'm considering using Matlab Compiler to distribute software for a price. I'm investigating (very) simple methods to discourage re-distribution without annoying users. Any recommendations?
One thought is to email a user a license key and have them input this during the installation process to be verified on a license server. If the key matches what is on the server, the installation proceeds as usual, otherwise, a warning message is shown to inform the user to purchase another license. However, this method requires a specified function to run only during the installation process, and not thereafter (so as not to annoy the user). Is this possible using Matlab Compiler or otherwise?
I suppose I could create a file on the user's disk that the program looks for when it starts (if it exists, then it is not being run for the first time), but if the user copies the whole directory, that file would get copied too.
In order to create an effective licensing system, you have to link it to one or more properties of a user machine (MAC address, OS ID, hard disk serial numbers, CPU serial numbers, etc...).
If you don't to this, you are just going to release licenses that can be transferred from one user to another. If one user decides to spread his license file worldwide, you are doomed because everyone could potentially take that license file and use it to unlock your application.
But if you link your license files to one or more properties of a user machine, as mentioned above, you must be able to obtain these properties either:
before the user decides to buy your application;
when the user activates his license.
First Scenario
You release your software as a trial. When it is started for the first time, you set an expiration date in the registry or in a file well hidden somewhere. You check against the expiration date when the application starts and, once it is reached, you throw an error and you don't let the used play with your application anymore.
Within the application, you create a Register Now button somewhere. When it is clicked, the application retrieves the machine properties and passes them to the web page / form that will be opened to let the user perform the payment. That page will be in charge to validate the machine properties, receive the payment and, finally, deliver a valid license code based on these properties.
Within the application, you must implement the same logics that allowed your form to create the license code, because you will need to use them in order to validate the code itself every time your application starts. A pseudo-code example:
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lc = GetLicenseCode();
if (~strcmp(sha1([mp1 mp2 mp3]),lc))
errordlg('Invalid license code!');
return;
end
This is the simplest path. But keep in mind that if one or more properties of the user machine change (because he changes a device or reinstalls his OS), his license will be invalidated and you will have to provide a customer assistance service that takes care of this kind of situations.
Second Scenario
This one is much harder. You will not be able to know the user's machine properties in advance. So your licensing system will work on a two-steps basis. You release a unique code (called LID for example) when the used purchases your application. Then, once the user inserts that it in your application, your application must send it back together with the machine properties. The final key (called LKey for example) is then computed and sent back to the user.
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lkey = GetLicenseKey();
if (~strcmp(sha1([mp1 mp2 mp3]),lkey))
errordlg('Invalid license code!');
return;
end
Machine Properties
The first solution has been provided to you through a comment: the MachineGuid value located in the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography. It's pretty solid. But it will only work on Windows machines. Use winqueryreg to access the registry.
Another good alternative is the Window Domain Controller Security ID, which is another machine-specific unique identifier. You can retrieve it using Java code within Matlab:
wdc_sid = com.sun.security.auth.module.NTSystem.getDomainSID();
or through the Windows registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership. The registry approach should be the one to use if you want to maintain a certain backward compatibility with old Matlab releases. Unfortunately, the Window Domain Controller Security ID is another identifier that is available only on machines that run under Windows.
If you want to adapt your licensing system to every possible OS and environment, you have to use a more generic approach, based on universally accessible hardware properties: MAC adresses, hard disk serials and such things. As far as I know, the most reliable property is the MAC address, because its uniqueness, althrough not granted, is almost certain and it's very unfrequent to change a network adapter (there are more chances to break an hard disk actually). Retrieve the MAC adresses of the machine network adapters using Java code as follows:
mac_addrs = '';
net_int = java.net.NetworkInterface.getNetworkInterfaces();
while (net_int.hasMoreElements)
mac_addr = net_int.nextElement.getHardwareAddress();
if (~isempty(mac_addr))
mac_addrs = [mac_addrs, '-', sprintf('%.2X',typecast(mac_addr,'uint8'))];
end
end
mac_addrs = mac_addrs(2:end);
The above computation produces a character array that represents the result of the concatenation of all the MAC addresses found on the machine. Again, for compatibility reasons, this may not work on old Matlab releases, so you have to use a much more complex approach, described here.
[EDIT]
This approach to retrieve the MAC address based on the underlying OS could be easier:
switch computer('arch')
case {'maci','maci64'}
[~,a]=system('ifconfig');
c=strfind(a,'en0');if ~isempty(c),a=a(c:end);end
c=strfind(a,'en1');if ~isempty(c),a=a(1:c-1);end
% find the mac address
b=strfind(a,'ether');
mac_add=a(1,b(1)+6:b(1)+22);
case {'win32','win64'}
[~,a]=system('getmac');b=strfind(a,'=');
mac_add=a(b(end)+1:b(end)+19);
case {'glnx86','glnxa64'}
[~,a]=system('ifconfig');b=strfind(a,'Ether');
mac_add=a(1,b(1)+17:b(1)+33);
otherwise,mac_add=[];
end
I found it in the comments of this article.