Jump to content

Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value


Kin

Recommended Posts

Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

Hello!

(1) I have been having some fun with the postprocessingplugin. It's really great! My biggest challenge has been that it is *hard* to troubleshoot the scripts, because the actual file is only run by cura, and so when the script completely fails, I only see that it won't load in Cura. And for some reason Cura takes ~25 seconds to open every time I open it, so that testing has quite some cycle time. I may be approaching it in a clunky way, I'm not sure (inexperienced here.)

(2) Specifically, right now I am trying to work out how to include if statements in the JSON header, to try and make it such that B,C,D parameters are input with default values depending on an option selected in enum parameter A. It appears something like this happens within CURA's regular JSON files. For example,

 

"infill_line_distance":                       {                           "label": "Infill Line Distance",                           "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.",                           "unit": "mm",                           "type": "float",                           "default_value": 2,                           "minimum_value": "0",                           "minimum_value_warning": "infill_line_width",                           "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == 'grid' else (3 if infill_pattern == 'triangles' or infill_pattern == 'cubic' else (4 if infill_pattern == 'tetrahedral' else 1)))",                           "settable_per_mesh": true                       }

 

So my code may look something like this:

 

"settings":           {               "machine_type":               {                   "label": "Machine Type",                   "description": "Select which machine type you are using. CRITICAL!",                   "type": "enum",                   "options": {                       "A":"A Type",                       "B":"B Type",                       "C":"C Type",                       "D":"D Type",                       "E":"E Type"                   },                   "default_value": "B"               },               "input_paramA":               {                   "label": "Second JSON",                   "description": "Beep bop boop",                   "unit": "mm",                   "type": "float",                   "default_value": 3,                   "value": "9999"                 },                   "default_value": 5 if machine_type == \"A\" else 3 if machine_type == \"B\" else 9               }

 

This specific version of the input_paramA is not working, but I have tried quite a few others (including comparing the machine_type without the \"\" modification.) Sometimes I can get the parameter to show up as a gcode modifying script, but never have I gotten the if statements to work. It seems at best the if statement doesn't know what machine_type means, or maybe I also have the application of if statements in the header incorrect.

I am trying to setup my input parameters based on a different method than the tweakAtZ script, because my reading of the tweakAtZ script is that a different input box is put up depending on which of a first selection box is chosen. In this you use the "enabled" modification. This works OK when you have 2 settings that depend on one of 2 choices (like at mm vs at layer.) But it doesn't scale well when you have 10 machine_types and 5 input parameters. It seems like there might be a better method for my application.

But, I am totally at a loss at this point. Any tips, help, or direction is appreciated! I'm still quite a python beginner.

  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    A few things that i notice with your json;

     

    • default_value can never have a python function, use value instead.
    • Things that need to be evaluated by python (such as; 5 if machine_type == \"A\" else 3 if machine_type == \"B\" else 9) need to be enclosed by ""
    • default_value must be a part of a setting.

     

    So if you take that into account, the json would be someting like

    "input_paramA":

    {

    "label": "Second JSON",

    "description": "Beep bop boop",

    "unit": "mm",

    "type": "float",

    "default_value": 5,

    "value": "5 if machine_type == \"A\" else 3 if machine_type == \"B\" else 9"

    }

  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Hi Nallath! I really appreciate the answer and help. I think you've got me further, and I see now the mistakes you pointed out. One thing I was not totally certain was what you meant by "default_value must be a part of a setting." I am not sure if you are saying "default_value must be used, even if you have a "value"" or something else.

    I paired down my normal script into just the JSON header, for debugging purposes. I have added your line

    "value": "6 if machine_type == \"A\" else 3 if machine_type == \"B\" else 9"

    to a previously working JSON header (for e.g, with just

    9

    instead) Unfortunately when I add the python statement line, the script no longer will load.

    Is there something obvious that I am doing wrong? I have really been butting my head on this quite a bit.

    I've copied the code below, and also attached to a public dropbox file here:

    https://dl.dropboxusercontent.com/u/3619097/Robust_Wipe.py

     

    from ..Script import Scriptimport reclass Robust_Wipe(Script):   version = "2.1"   def __init__(self):       super().__init__()   def getSettingDataString(self):       return """{           "name":"Robust Wipe """ + self.version + """",           "key":"Robust_Wipe",           "metadata": {},           "version": 2,           "settings":           {               "machine_type":               {                   "label": "Machine Type",                   "description": "Select which machine type you are using. CRITICAL!",                   "type": "enum",                   "options": {                       "A":"A Type",                       "B":"B Type",                       "C":"C Type",                       "D":"D Type",                       "E":"E Type"                   },                   "default_value": "A"               },               "input_paramA":               {                   "label": "Input",                   "description": "First Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 5,                   "value": "6 if machine_type == \"A\" else 3 if machine_type == \"B\" else 9"               }           }       }"""   def execute(self, data):       if 1==1:           pass           #I want the most basic version of the script for figuring out JSON       return data

     

  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

     One thing I was not totally certain was what you meant by "default_value must be a part of a setting.

     

    It means that this;

    "bla": {"default_value":10} is allowed.

    "bla": {}, "default_value": 10 is not allowed.

     

    Unfortunately when I add the python statement line, the script no longer will load.

     

    I don't see anything obviously wrong, but why don't you try to keep it as simple as possible first? Try something like "6 if machine_type == 'A'" and see what happens. If that works, increase the complexity.

  • Link to post
    Share on other sites

    Posted (edited) · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Hi Nallath! Thanks!

    Wow, I did not realize that in the first code I wrote I had "default_value" outside of the setting. :O. That was a huge mistake. I hope it wasn't in all of the versions I had tried, or else I wasn't ever going to get anywhere.

    I think you are right of course about trying to keep it simple. I went back to testing just

     

    default_value:6

     

    and then

    value:"6 if machine_type == \"A\"" but not luck

    I do wish I had a better sense of the error, since it feels extremely hard to debug otherwise. Difficult for an amateur, I guess, maybe feasible for someone more versed with this kind of scripting & JSONs.  (Also, given that Cura takes 30 seconds to load on my SSD laptop [not on all the computers I've used though] it takes extra long to test all the changes.)

    Edited by Guest
  • Link to post
    Share on other sites

    Posted (edited) · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Interestingly, I got somewhere with

     

                       "value": "6 if machine_type == A"

     

    But it is kind of faulty.  That is, at least the script loads, but the box is red and unhappy. It does let you enter numbers though, but it doesn't preload 6.

    Edited by Guest
  • Link to post
    Share on other sites

    Posted (edited) · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Never made it further with this. Unfortunately I think I'm stuck hard coding things into the script and then adding override settings.     I wish I understood JSON a little better or had a better sense of how to debug the scripts given the issue of no error reporting. It's been a bit of a frustrating struggle. Overall still cool to have the postprocessing plugin so not to air my frustrations as an overall negative review. It's great :D.

    Edited by Guest
  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Interestingly, I got somewhere with

     

                       "value": "6 if machine_type == A"

     

    But it is kind of faulty.  That is, at least the script loads, but the box is red and unhappy. It does let you enter numbers though, but it doesn't preload 6.

     

    Hi. I've been lurking and following this thread. From what I'm understanding, shouldn't this be:

     

    "value": "6 if machine_type == \"A\""

     

    I also sent you a PM (just saw yours - sorry). Maybe I can help...

  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Hi. I've been lurking and following this thread. From what I'm understanding, shouldn't this be:

     

    "value": "6 if machine_type == \"A\""

     

     

    Hi DaHai!

    I agree, I think per my fledgling understanding so far, the double quotes would be necessary. However, when I add them, the script that partially works doesn't load, even if that is the only change. I have the script attached and I just reran the tests. I'm sending the double quote version, which you will see can't load, and then if you take out the \"\" then it loads, but doesn't process the if statement looking for the "A". https://dl.dropboxusercontent.com/u/3619097/Robust_Wipe.py

    I don't really know what fails when I add the quotes, just that it fails.

    Right now although I would love to understand what I'm doing wrong, I admit I think I'm moving towards adding a third type "custom" and just looking at a set of always-on values only if custom is selected. Unfortunately this means the built-in values aren't displayed per type, which was really my ideal and a more robust script. At least, I'm glad to now have a slightly better sense of how the JSON is formatted and works, but I have been really stuck getting it right.

  • Link to post
    Share on other sites

    Posted (edited) · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Alrighty, here we go:

     

    "value": "6 if machine_type == 'A' else (3 if machine_type == 'B' else 9)"

     

    Now, following this pattern, I believe additional logic would be nested like so:

     

    "value": "6 if machine_type == 'A' else (3 if machine_type == 'B' else (4 if machine_type == 'C' else 9))"

     

    And that does work in testing with Cura 2.3.0...

    So, with each additional 'if' logic, you'd need another level of nested parens

    P.S. Forgot to mention: It appears every IF must have an ELSE. The Default value does not take effect if the IF fails.

    Edited by Guest
    • Like 1
    Link to post
    Share on other sites

    Posted (edited) · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    I'm at work right now, but I will process this tonight after work and go through the response.

    Thank you!!

    Edit: Update, gah! Wasn't able to work on it today after work (long day) but hope to tomorrow.

    Edited by Guest
  • Link to post
    Share on other sites

    Posted · Looking for help w/ PostProcessingPlugin JSON formatting - how to include if statements based on first value

    Update: So this totally went wayside during the holiday madness :O. I am glad to have finally sat down on it. Dahai8 you uncovered the secret. I've include below the example code you gave extended to a more complicated number of parameters.

    I still have had a bear with opening cura to test edits to the script, but mostly it's just me not being a cautious practiced programmer and missing punctuation. I probably rely too much on (for example) the compiler in arduino to point out such issues. I don't get so lucky with the gcode modifier script because I never see how it fails in cura (just that it doesnt load, which no longer is an issue.)

    Thanks again for all the help! Very happy to have done this as neatly as extensively as I hoped would be possible. Only due to the json hacking help of others.

     

    from ..Script import Scriptimport reclass Robust_Wipe(Script):   version = "2.1"   def __init__(self):       super().__init__()   def getSettingDataString(self):       return """{           "name":"Robust Wipe """ + self.version + """",           "key":"Robust_Wipe",           "metadata": {},           "version": 2,           "settings":           {               "machine_type":               {                   "label": "Machine Type",                   "description": "Select which machine type you are using. CRITICAL!",                   "type": "enum",                   "options": {                       "A":"A Type",                       "B":"B Type",                       "C":"C Type",                       "D":"D Type",                       "E":"E Type"                   },                   "default_value": "A"               },               "wipe_layer":               {                   "label": "Wipe Frequency",                   "description": "Wipe every N layers",                   "unit": "Layers",                   "type": "int",                   "default_value": 1               },               "wipe_volume":               {                   "label": "Wipe Volume",                   "description": "Wipe every N layers and volume - not implemented",                   "unit": "mm",                   "type": "float",                   "default_value": 0               },               "input_paramA":               {                   "label": "Input A",                   "description": "First Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramB":               {                   "label": "Input B",                   "description": "Second Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramC":               {                   "label": "Input C",                   "description": "Third Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramD":               {                   "label": "Input D",                   "description": "Fourth Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramE":               {                   "label": "Input E",                   "description": "Fifth Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramF":               {                   "label": "Input F",                   "description": "Sixth Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },               "input_paramG":               {                   "label": "Input G",                   "description": "Seventh Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               },                "input_paramH":               {                   "label": "Input H",                   "description": "First Input Parameter",                   "unit": "mm",                   "type": "float",                   "default_value": 99,                   "value": "1 if machine_type == 'A' else (2 if machine_type == 'B' else (3 if machine_type == 'C' else (4 if machine_type == 'D' else (5 if machine_type=='E' else 9))))"               }           }       }"""   def execute(self, data):       if 1==1:           pass           #I want the most basic version of the script for figuring out JSON       return data

     

  • Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    • Our picks

      • UltiMaker Cura 5.7 stable released
        Cura 5.7 is here and it brings a handy new workflow improvement when using Thingiverse and Cura together, as well as additional capabilities for Method series printers, and a powerful way of sharing print settings using new printer-agnostic project files! Read on to find out about all of these improvements and more. 
         
          • Like
        • 18 replies
      • S-Line Firmware 8.3.0 was released Nov. 20th on the "Latest" firmware branch.
        (Sorry, was out of office when this released)

        This update is for...
        All UltiMaker S series  
        New features
         
        Temperature status. During print preparation, the temperatures of the print cores and build plate will be shown on the display. This gives a better indication of the progress and remaining wait time. Save log files in paused state. It is now possible to save the printer's log files to USB if the currently active print job is paused. Previously, the Dump logs to USB option was only enabled if the printer was in idle state. Confirm print removal via Digital Factory. If the printer is connected to the Digital Factory, it is now possible to confirm the removal of a previous print job via the Digital Factory interface. This is useful in situations where the build plate is clear, but the operator forgot to select Confirm removal on the printer’s display. Visit this page for more information about this feature.
          • Like
        • 0 replies
    ×
    ×
    • Create New...