run lisp every hour

run lisp every hour

DGRL
Advisor Advisor
2,309 Views
12 Replies
Message 1 of 13

run lisp every hour

DGRL
Advisor
Advisor

Dear members,

 

Is it possible to run an lisp automatically every 60 minutes for example?

IF possible can someone provide me an code?

 

Best regards,

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
2,310 Views
12 Replies
Replies (12)
Message 2 of 13

john.uhden
Mentor
Mentor

This could probably be done by setting up a reactor.  But reactors fire only in relation to an event taking place.  So for instance if the reaction was tied to the use of the EXPLODE command, but the EXPLODE command wasn't used all day, then the reactor would never fire. But if the reactor was tied to a system variable change, such as TDUSRTIMER, then it would fire continuously and probably slow down your AutoCAD to a crawl.

 

Might there be any particular event that you would want to cause the reactor to fire?

John F. Uhden

0 Likes
Message 3 of 13

Kent1Cooper
Consultant
Consultant

Do some Searching in this Forum.  Things very like this have come up before, though mostly in relation to Saving in various ways [for example, to periodically Save to a different version, or to a .DXF  file, unlike what AutoSave functionality does].  You'll find all the discussion of possible approaches, the difficulties inherent in the idea, etc.

Kent Cooper, AIA
0 Likes
Message 4 of 13

ActivistInvestor
Mentor
Mentor

@DGRL wrote:

Dear members,

 

Is it possible to run an lisp automatically every 60 minutes for example?

IF possible can someone provide me an code?

 

Best regards,

 

 


Does that include when AutoCAD is running but no one happens to be using it (e.g., int the background, or the computer itself is not being used) ?

0 Likes
Message 5 of 13

Kent1Cooper
Consultant
Consultant

@Activist_Investor wrote:

Does that include when AutoCAD is running but no one happens to be using it (e.g., int the background, or the computer itself is not being used) ?

That's one of the "difficulties inherent in the idea" I mentioned.  If you have multiple drawings open, and some of them have had nothing done in them for the past hour, should it run in all of them anyway?  If you've switched over to Internet searching or Word processing or Spreadsheeting or something, and AutoCAD is just sitting there doing nothing for an hour, should it run anyway?  If you've gone to a meeting....?  Etc., etc.

Kent Cooper, AIA
0 Likes
Message 6 of 13

DGRL
Advisor
Advisor
Hi @ Kent1Cooper, Just make it simple indeed and let it run every hour. We can adjust it later if needed right?
If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 7 of 13

john.uhden
Mentor
Mentor

Please reread post #2.  Maybe in some other programming language you can automatically fire off a reaction without an event, but not so with just Visual Lisp.  There has to be an event that triggers the reaction.  It could be any command or change in any sysvar, obviously something that takes place more frequently than once in a hour, but not every nanosecond.  But maybe we ought to test out using TDUSRTIMER and see if it really slows things down to the extent that I suspect.  Maybe I can try it out over the weekend.  But fear not; someone else here will probably have your answer in a few minutes, if not already.

John F. Uhden

0 Likes
Message 8 of 13

Kent1Cooper
Consultant
Consultant

@john.uhden wrote:

....  There has to be an event that triggers the reaction.  It could be any command .... we ought to test out using TDUSRTIMER and see if it really slows things down ....


One possibility [similar to but I think simpler than creating a Reactor] is to Undefine and then make a new definition of  some commonly-used command, add a check on TDUSRTIMER for whether it has passed an hour [0.041666 days], and if so, run the routine, including resetting the timer with a Time command, and then proceed with the requested command; if not, just proceed with the command.

 

But it kind of depends on what the routine should do.  For instance, I like to work with Blips turned on, which means I use Redraw occasionally, and since that doesn't involve any further input, redefining that to include such a check would be "invisible" to the User if the routine doesn't make any requests of them, and wouldn't interrupt anything.  The same might be done with other transparent-capable commands, but some of those [like Zoom and Pan and Layer] are more commonly done in newer versions without the commands themselves, e.g. mouse-wheel display manipulations wouldn't trigger it if it's embedded in a new definition of the Zoom command.  But if whatever it should do involves commands that can't  be transparent, and/or it has to get User input or confirmation or something, then you would want to think carefully about which command to redefine, e.g. would you want to start a Line command and have it occasionally interrupt, and ask for input about something else?  In such a case, should it ask first, or after you've drawn your Line(s)?  Etc., etc.  It would presumably have to be some command you use often enough that it's likely to be triggered after not much more than any given hour's time.  The best candidate would depend on the nature of your work, e.g. do you Insert Blocks or draw Polylines more often than you draw Lines?

 

That kind of approach has the advantage that even if you have several drawings open, or you are using other programs for a while, or go out to lunch, those drawings in which nothing happens for a long time won't have the routine run in them unnecessarily.  But there is the potential that some drawing was getting close  to the hour cut-off, and ought  to have the routine run [e.g. for safety if it involves some kind of Saving], but wouldn't have it run until you get back into it and do the triggering command again.  That means if, for example, AutoCAD crashes, such a drawing won't have had it run, and [again if Saving is involed] work could be lost.

Kent Cooper, AIA
0 Likes
Message 9 of 13

Anonymous
Not applicable

It would probably be easier to find and download a desktop app that has an hourly reminder to get a cup of coffee.

0 Likes
Message 10 of 13

john.uhden
Mentor
Mentor

Ahah!  Get an alarm clock app that can send a command to AutoCAD.

John F. Uhden

0 Likes
Message 11 of 13

john.uhden
Mentor
Mentor

Your superfluity daunts me, but your first paragraph represents a decent idea, that is until all the users start typing ".line" and ".move" etc.  I tried that idea back in the early 90s, before reactors.  It met with limited success.

John F. Uhden

0 Likes
Message 12 of 13

ActivistInvestor
Mentor
Mentor

@DGRL wrote:

Dear members,

 

Is it possible to run an lisp automatically every 60 minutes for example?

IF possible can someone provide me an code?

 

Best regards,

 

 


I think it would be a good idea for some participants in this thread to try to avoid confusing puzzles with problems (e.g., in this place, a puzzle is a problem that must be solved entirely with LISP, without the aid of any other type of programming/scripting etc.). IOW, it's a game of sorts. Smiley Wink

 

You came here with a problem, not a puzzle.

 

The problem can be easily solved, using just about any Windows development tool, like VB, .NET, etc., and it would take about 10 minutes to write (specifically, an ActiveX client that uses a Timer as a trigger to send a command to AutoCAD that executes the LISP macro). And yes, it can do that as often as you want, and it can also be done intelligently so that it waits until AutoCAD is not busy, rather than being disruptive and interrupting you while you're using a command.

 

I'm not going to write it for you, but you should be able to find someone who would be willing to do that or may already have done so, perhaps in one of the other forums that deal with Windows development tools (try the VBA/ActiveX forum, or the .NET forum).

0 Likes
Message 13 of 13

john.uhden
Mentor
Mentor

Below are a few functions that create/use a reactor as a kind of alarm to call another function after X many minutes input by user.

The whole thing is based on a vlr-sysvar reaction.

The first function is the reactor callback function.

The second (C:) function can be used at the command line to set the time interval and take the "alarm" function (as a string) to perform inside the reaction.

The third function can be called from within any lisp and takes arguments for the "alarm" function and interval in minutes.

 

When using the command function, you can enter the "alarm" function without quotes, as in (alert "TIME TO WAKE UP\nIT'S WAGON WHEEL TIME")

When using the third function (@setalarm), you must provide the "alarm" function argument as a string, as in "(alert \"WAKE UP\")"

 

Sadly, but understanably, the vlr-sysvar-reactor does not respond to sysvars like DATE, or CDATE, or TDUSRTIMER, or VIEWCENTER.  But I figure we all turn on and off OSMODE plenty, or switch layouts.  I hope this is good enough to be helpful to someone.

 

I have not tested it with anything more than (alert), so I can't tell you what might happen with something more complicated.  I am very sure that if the function you call changes any applicable sysvar, then the reactor will fire again and again and will probably blow up your session.  If needed, I do have a way around that.

 

(defun @sysvar_reactor (Reactor Info / Reaction Test DATE)
   (or *doc* (setq *doc* (vla-get-activedocument *acad*)))
   (setq Reaction (vlr-current-reaction-name)
              DATE (getvar "DATE")  ;; Units are days
   )
   ;; The next two lines are for creating a global list of sysvars that have triggered the reaction
   ;; Note that sysvars such as DATE, CDATE, TDUSRTIMER, and VIEWCENTER  do NOT trigger.
   (setq sysvar (car info))
   (or (vl-position sysvar sysvars)(setq sysvars (cons sysvar sysvars)))
   (cond
     ((not **LAST_DATE**)(setq **LAST_DATE** DATE))
     ((not **INTERVAL**))
     ((/= (type **ALARM_FUNCTION**) 'LIST))
     ((>= DATE (+ **LAST_DATE** (/ **INTERVAL** 1440.0)))
       (eval **ALARM_FUNCTION**)
       (setq **LAST_DATE** DATE)
     )
   )
   (princ)
)
(defun c:setalarm ( / str interval ok)
  (while (not ok)
    (initget 1)
    (setq str (getstring T "\nEnter alarm function to run: "))
    (if (= (type (read str)) 'LIST)
      (setq  ok 1)
      (prompt "\nInvalid function.  Please reenter.")
    )
  )
  (initget 5) ;; require input and disallow negative values
  (setq interval (getint "\nEnter alarm interval in minutes (0 to turn off): "))
  (@setalarm str interval)
)
(defun @setalarm (func interval / ok)
    (if (and (= (type func) 'STR)(= (type (read func)) 'LIST))
      (setq **ALARM_FUNCTION** (read func) ok 1)
      (prompt "\nInvlaid function")
    )
    (if (and  ok (numberp interval)(> interval 0))
      (setq **INTERVAL** interval ok 1)
      (setq ok (prompt "\nInterval must be greater than or equal to 0."))
    )
    (cond
      ((not ok))
      ((> **INTERVAL** 0)
        (if (/= (type $sysvar_reactor) 'VLR-SysVar-Reactor)
          (setq $sysvar_reactor
            (vlr-SysVar-reactor "Uhden Sysvar Reactor"
              '((:vlr-sysVarChanged . @sysvar_reactor))
            )
          )
        )
        (or (vlr-added-p $sysvar_reactor)(vlr-add $sysvar_reactor) 1)
        (setq  **LAST_DATE** (getvar "DATE"))
        (princ (strcat "\nAlarm has been set at " (menucmd "M=$(edtime,$(getvar,date),HH:MM:SS)")))
        (princ (strcat "\nAlarm will go off in " (itoa **INTERVAL**) " minute(s)."))
      )
      ((and
          (= (type $sysvar_reactor) 'VLR-SysVar-Reactor)
          (vlr-added-p $sysvar_reactor)
          (or (vlr-remove $sysvar_reactor) 1)
          (not (setq $sysvar_reactor nil))
          (princ "\nAlarm has been turned off.")
        )
     )
  )
  (princ)
)

John F. Uhden

0 Likes