TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: David Bethel on January 27, 2018, 10:27:09 AM

Title: Project Value Concept
Post by: David Bethel on January 27, 2018, 10:27:09 AM
Greetings,

Back in 2002+-, I worte an routine for a customer that I knew was
very useful to them ( and a great education for me).  I did
not foresee that 15+ years later they are still using it and they
actually claim it is 1 one of their best employees  <g>.  I was
well paid ( for that time ) and assigned them the copyrights ( which I
do not regret).

I now know that I way under priced the value of the product.

Today, I am developing a entirely new concept for the company
that evolved from that and I know it will be useful and valuable to them
for a LONG time in the future.  I know it would also be valuable
to their competitors.

I am considering a scenario where each time the program is succesfully
run, that a notice/email/record is sent to a url/email_client/sql for
a weekly/monthly/yearly subscrition billing.

Has anyone any experience / input / suggestiuons ?

TIA  -David
Title: Re: Project Value Concept
Post by: Grrr1337 on January 27, 2018, 12:24:24 PM


Hi David,
Writing from no experience...
I'd suggest the classical date/time checking, (and the important .lsp->.vlx conversion ofcourse) with a small addition:

Code: [Select]
(cond
  ( (not (member (get_mac_address) list_of_my_mac_addresses)) (alert "UnAuthorised user.") ) ; would be a good idea to tighten-up the range of users
  ( expired (alert "This program expired, contact David...") )
  (t
    (if one_week_or_month_left_till_expire
      (alert (strcat "\nThis program expires in " n " days, contact David..."))
    )
    (main)
  )
); cond

As for the lazy subscrition maintainance:
I'd create a predefined list of passwords, where each password corresponds to the given range of time.
So everytime the routine expires, the client would contact you for the password:

Code: [Select]
(and ; weekly/monthly/yearly subscrition billing
  (setq pwd (getstring t (strcat "\nInput Password for " (menucmd "M=$(edtime,$(getvar,date),MONTH YYYY)") ": ")))
  (setq d (substr (rtos (getvar 'cdate) 2 5) 1 8))
  (vl-some
    '(lambda (x) (and (wcmatch d (car x)) (= (strcase pwd) (strcase (cdr x)))))
    '(
      ("201801##" . "Jan2018pwd") ; Password for January 2018
      ("201802##" . "Feb2018pwd") ; Password for February 2018
      ("201803##" . "Mar2018pwd") ; Password for March 2018
    )
  ); vl-some 
  (princ "\nPassword correct.")
); and

So say create a list of password just for the next 2 years, and till the password list expires, you might done a new version of the program that contains a completely new list of passwords.

Title: Re: Project Value Concept
Post by: MP on January 27, 2018, 01:55:54 PM
Couple thoughts ...
tl;dr: There are few things as annoying (i.e. motivate abandoning) as an app that is frequently trying to contact the mothership and/or is over zealous in its licensing scheme.
Title: Re: Project Value Concept
Post by: MickD on January 27, 2018, 08:06:20 PM
This is a tough one but you need to consider that you probably wouldn't get the work if 'they' didn't need it so in a way they are creating you a job and an opportunity to make a few bucks.

Having said that you should charge a premium rate given that it will save them a lot of time/money in the long run, that is, it has good intrinsic value.
From my experience, if you want to charge them a subscription then it won't be 'their' technology even though they fully funded it. It doesn't go down well.

One solution would be to offer a yearly 'service agreement' fee, maybe based on user numbers, maybe just a sizable lump sum that you would be happy with to cover updates and basic support each year (you can still charge again for new features) so at least you still get some sort of cut each year.  I know, it sounds like a subscription but it makes them feel like the owner and it looks better on their books ;)
Just make sure it's more than reasonable for you, but not a figure they are likely to baulk at.
Title: Re: Project Value Concept
Post by: BIGAL on January 27, 2018, 10:17:51 PM
I wrote one piece of code and finished the 1st version it saved a massive amount of time drafting. It was given to the client to test out, we had a simple check serial numbers, they wanted an open version code for unlicensed Autocad. We said we would not support them so the coding improvements ceased and we did not get paid, a few years later called into a consulting firm offering coding service and they advised they had this great program they used every day, I mentioned we had not been paid for it and the mood changed, the company had bought out the prior one.

It is hard to not sell to end user competitors, holding some form of copyright agreement is worthwhile. With internet now it makes sense to charge on a as used base. Where I am now we pay a company around $1 per enquiry it was costing us say $5 or even more for each one. Its like $50k / year.

The only downside is you will need your own URL but I expect you have that now, a lot of providers give you say 1 Gb of space as part of service. You can send a message text file every time the code is used to a URL rather than a email. I am pretty sure append is an option so 1 file recording.

With a service agreement then everyone knows they are paying including competitors.
Title: Re: Project Value Concept
Post by: David Bethel on January 28, 2018, 10:54:38 AM
Thanks for the inputs !

I know this client really well. 

The main user will be an in office engineering department that will
have an Internet connection.  ( unless Mr. Gates' flunkies screw up )

If it is used by anyone else, it would be a demonstration or a training
seminar / trade show booth.  I'm not too worried about these type of things.
They will be the only users / owners.

We have reciprocating NDAs with ownership and copyright issues under control.

I'm thinking that upon exiting the routine, in addition to resetting modes &
variables etc, either write and call a bat file or add an autolisp call to
connect our in house URL.  Nothing fancy.  Maybe (dos_date) & (dos_time).
Nothing would occur during the actual run time.

Our web server has a log file that could be accessed in need be.  We also have
a couple static IP addresses that are not being used.  I could easily setup a
new server.  Just no DNS connections.

-David
Title: Re: Project Value Concept
Post by: VovKa on January 28, 2018, 01:12:44 PM
Our web server has a log file that could be accessed in need be.
add vla-GetRemoteFile call that will point to a (non)existing and unique page on you server then just analyze the logs
Title: Re: Project Value Concept
Post by: MickD on January 28, 2018, 04:08:37 PM

I'm thinking that upon exiting the routine, in addition to resetting modes &
variables etc, either write and call a bat file or add an autolisp call to
connect our in house URL.  Nothing fancy.  Maybe (dos_date) & (dos_time).
Nothing would occur during the actual run time.


It's very easy to set up a LAMP (Linux) or WAMP (Windows) stack on your server to handle your logging. You could then have a simple PHP file to handle the logging request, all you need to do is send something like the following string to the logging server:

Code - PHP: [Select]
  1. <server_url_string>/logger.php?dos-date=5/6/2018_09:34:42_PM&user=Tom_Thumb
  2.  

The logger.php script will extract those variables from the request and you can store them in a db or text file as you need. I'd use a db just for the power of being able to filter data and other tasks that pop up over time.
Title: Re: Project Value Concept
Post by: David Bethel on January 29, 2018, 07:18:24 AM
HHmm  I hadn't thought of php.  I never was that good at it and what little I knew is probably so rusty I'll never remember it.

Maybe append a text file with the date and time and IP address of the sender ( if that is possible )


Thanks  -David
Title: Re: Project Value Concept
Post by: ChrisCarlson on January 29, 2018, 08:40:19 AM
I'm confused as to what you would gain with weekly/monthly/yearly usage reports? Speaking from a company perspective, I would prefer one large up-front cost than a monthly fee. There is nothing worse than requesting purchase approval, coordinating with purchasing to pay it, and then finally completing an expense report. Also, with a subscription you will be liable for any and all updates as it relates to AutoDesk breaking things.

Personally, I would avoid AutoLISP at all costs and move it to .NET, there is much more long term success available.

Also, I would not hard code any subscription checks without first incorporating a self-updating function.
Title: Re: Project Value Concept
Post by: David Bethel on January 29, 2018, 09:57:21 AM
I'm really not looking for a subscription fee.  More of a pay per click.

So it's not actually usage report in the standard sense.  The total number of times a php file records activity is billing for that period would be extracted and an invoice generated.  Probably monthly.

If they don't use it or need any longer, it gets abandoned.  Once proven to do as stated, updates are not required unless the customer requests additions or changes.

I have several customers that I have running POs with.  When the funds are used they simply refill the PO with a predetermined amount.

.NET is not my cup of tea.  I have 25+ years with AutoLISP (vanilla only).

-David
Title: Re: Project Value Concept
Post by: dgorsman on January 29, 2018, 10:17:45 AM
It would be good to ensure there is a short-term solution in case of internet outage or similar problems, something that allows them to run for a day or two.

You also might want to implement some kind of per-project breakdown in the logging/billing system.  This is increasingly sought after so management has a better understanding of where costs actually go, rather than averaging it out over some arbitrary number.
Title: Re: Project Value Concept
Post by: David Bethel on January 29, 2018, 10:29:19 AM
Whatever I do it will be upon exiting the routine and be non-invasive.  If all I want to do is to call a URL.  If the URL it doesn't acknowledge the ping, so be it.  I can always go back and check the server log files for error reports.

Almost everyone in my industry so totally internet dependent these days.

This is more of a concept of proving a system can work and not be a RPIA for the customer.

Thanks  -David
Title: Re: Project Value Concept
Post by: MickD on January 29, 2018, 03:28:08 PM
HHmm  I hadn't thought of php.  I never was that good at it and what little I knew is probably so rusty I'll never remember it.

Maybe append a text file with the date and time and IP address of the sender ( if that is possible )


Thanks  -David

I reckon the whole script would be under 100 LOC and it is the very basics of using a POST request and inserting a simple record to a database.
SQLite would be fine for this so you don't need to set up a db server, it's just like using a text file but has search capabilities which would be handy for project breakdowns and other search queries as dgorsman mentioned.
A text file sounds like the easiest way but you are dealing with transactions of value and one day they will want to know more about what they've done so dig in now and you'll be much better off in the future.

As a fall back system if the net is down (you should receive a 200 response from the server if all is ok with the transaction) you could log to a local SQLite db and check/update when the net is available again.

These technologies are not hard to learn and understand and with some good commenting you'll be able to grok what you did a few years from now. PHP is the most used web scripting language out there and there are mountains of example code to do what you want to do.

If I get time today I'll whip up an example, cheers.
Title: Re: Project Value Concept
Post by: MickD on January 29, 2018, 05:36:53 PM
Here's a very simple sample of handling the data on the server, you could easily create a few simple html/PHP pages to view data etc.
There are also tools to help with SQL and the database, I use DB Browser for SQLite, it works well.

It's a tad over 100 LOC but there's a lot of cruft and comments :)
Place this into an index.php file in a folder in your XAMPP or WAMP (Windows) www or htdocs directory. You can then browse to localhost:80/myfolder/index.php and enter data. Go 'back' to enter more data.

Code - PHP: [Select]
  1. <?php
  2.  
  3. // index.php for swamp-logger
  4. //
  5. // Purpose:
  6. // To gather the POST values to be inserted into an SQLite db
  7.  
  8. // NOTES:
  9. // A Windows apache server needs to make sure the php_sqlite.dll and the php_pdo.dll
  10. // is enabled in the php.ini file.
  11.  
  12. // check if the request for this file is a 'post' request,if not send the form
  13. // back with and error if any:
  14. if($_POST && isset($_POST['user'], $_POST['drawing_no'])){
  15.  
  16.     // get the posted values:
  17.     $user = $_POST['user'];
  18.     $drawing_no = $_POST['drawing_no'];
  19.  
  20.     // establish the db connection:
  21.     $pdo = get_db();
  22.  
  23.     // insert the data:
  24.     $id = insert_log_data($pdo, $user, $drawing_no);
  25.     // you could check here for the id and handle it if it's null/not there.
  26.     if($id){
  27.         // just echo something back to the user:
  28.         echo "Data with ID " . $id . " logged successfully!";
  29.     }
  30.  
  31.     // close the db:
  32.     $pdo = null;
  33.  
  34. } else {// it's not a POST or there's and error or missing data, send the form:
  35.  
  36. // --------- FORM SECTION (used for testing, can be deleted) -------------- //
  37.  
  38. ?>
  39. Please enter information in all fields!
  40. <form action="" method="post">
  41.     Name:           <input type="text" name="user" /><br/>
  42.     Drawing Number: <input type="text" name="drawing_no" /><br/>
  43.     <input type="submit" value="Submit Log Details" />
  44. </form>
  45.  
  46. <?php
  47. } // end else.
  48.  
  49. // --------- END FORM SECTION --------------------------------------------- //
  50.  
  51.  
  52. // Returns an SQLite PDO connection object ready for use.
  53. function get_db(){
  54.     try{
  55.         // create the PDO conn object:
  56.         $pdo = new PDO('sqlite:usage_log.sqlite3');
  57.  
  58.         // query to create the table if not exists:
  59.         $create_query = "
  60.            CREATE TABLE IF NOT EXISTS usage_log(
  61.                id INTEGER PRIMARY KEY,
  62.                user TEXT,
  63.                drawing_no TEXT,
  64.                datetime TEXT
  65.            )";
  66.  
  67.         // this will just exit if the table exists:
  68.         $pdo->exec($create_query);
  69.  
  70.         // return the PDO object:
  71.         return $pdo;
  72.     }
  73.     catch(PDOException $e){
  74.         echo $e->getMessage();
  75.     }
  76. }
  77.  
  78.  
  79. // Inserts the sanitized data into the db, PDO does handle sanitization to
  80. // avoid sql injection but you may need handle the input from a html user form
  81. // more strictly.
  82. function insert_log_data($pdo, $user, $drawing_no){
  83.     try{
  84.         // build the query string as a 'prepared statement':
  85.         $sql = "INSERT INTO usage_log(user, drawing_no, datetime)
  86.            VALUES (:user, :drawing_no, :datetime)";
  87.  
  88.         // get the current datetime stamp (may need to set timezone):
  89.         // eg: date_default_timezone_set('UTC');
  90.         $datetime = date("Y-m-d H:i:s");
  91.  
  92.         // prepare and execute the statement with the args passed in:
  93.         $stmt = $pdo->prepare($sql);
  94.         $stmt->bindValue(':user', $user);
  95.         $stmt->bindValue(':drawing_no', $drawing_no);
  96.         $stmt->bindValue(':datetime', $datetime);
  97.         $stmt->execute();
  98.  
  99.         // we can return the last inserted id (our new record):
  100.         return $pdo->lastInsertId();
  101.     }
  102.     catch(PDOException $e){
  103.         echo $e->getMessage();
  104.     }
  105. }
  106.  
  107.  
  108.  
Title: Re: Project Value Concept
Post by: David Bethel on January 30, 2018, 06:05:34 AM
WOW !   Thanks !  I'll need to digest this !  Regards  -David
Title: Re: Project Value Concept
Post by: MickD on January 30, 2018, 03:03:44 PM
No worries, just holler if you have questions.
Title: Re: Project Value Concept
Post by: Lee Mac on January 30, 2018, 05:13:05 PM
Mick, your generosity & willingness to share your wealth of knowledge is commendable.  :-)
Title: Re: Project Value Concept
Post by: MickD on January 30, 2018, 06:22:27 PM
Mick, your generosity & willingness to share your wealth of knowledge is commendable.  :-)

Thank you Lee, coming from you that means a lot, cheers :)
Title: Re: Project Value Concept
Post by: JohnK on January 30, 2018, 07:33:54 PM
MickD, you appreciate this. I was just reading this yesterday (weird coincidence).
https://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm
Title: Re: Project Value Concept
Post by: MickD on January 30, 2018, 07:54:01 PM
MickD, you appreciate this. I was just reading this yesterday (weird coincidence).
https://www.tutorialspoint.com/cplusplus/cpp_web_programming.htm

A good read and pretty thorough tutorial, thanks John :)

I've seen the cgi-bin directory on my server but never really went much further. I'm not sure about C++ and html though, seems like hard work, that's why Rasmus Lerdorf created PHP :)
It's well worth a read though and will definitely give it a go for the exercise. I'd also like to try it with Golang which is a bit easier to work with I reckon :)
Title: Re: Project Value Concept
Post by: JohnK on January 30, 2018, 08:22:30 PM
Yeah I was also trying to imagine the work-flow for a c++ web app and it became quite mind numbing quickly but I still wanted to give it a go once (for the kicks). :)
Title: Re: Project Value Concept
Post by: David Bethel on January 31, 2018, 06:59:19 AM


Very interesting indeed. 

My server has cgi-bin directory ( empty of coarse )  -David
Title: Re: Project Value Concept
Post by: JohnK on January 31, 2018, 07:53:11 AM
That's because you are most likely using Apache and by default, Apache Web Server is configured to run CGI programs in /var/www/cgi-bin.