nodel-recipes

Write Nodel node recipes (script.py) using Jython 2.5 - define actions, events, parameters, TCP/UDP/HTTP protocols, and device control logic. Use when creating or modifying Nodel scripts.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "nodel-recipes" with this command: npx skills add scroix/nodel-skills/scroix-nodel-skills-nodel-recipes

Nodel Recipe Development

Critical: Jython 2.5 Syntax

Node scripts execute under Jython 2.5.4. You MUST use Python 2.5-era syntax:

# CORRECT - Python 2.5 syntax
except Exception, e:
    console.error('Error: %s' % e)

# WRONG - Python 3 syntax (will fail)
except Exception as e:
    console.error(f'Error: {e}')

See references/jython-syntax.md for complete syntax reference.

Recipe File Structure

A node recipe lives in a folder containing:

  • script.py - Main recipe logic (required)
  • content/index.xml - Custom frontend definition (optional)
  • content/css/custom.css - Custom styles (optional)
  • content/js/custom.js - Custom JavaScript (optional)

Core Concepts

Parameters

Configure node behavior via the web interface:

param_ipAddress = Parameter({'title': 'IP Address', 'schema': {'type': 'string'}})
param_port = Parameter({'title': 'Port', 'schema': {'type': 'integer'}, 'default': 9999})

Local Actions

Commands this node exposes (can be triggered by bindings or REST API):

@local_action({'schema': {'type': 'string', 'enum': ['On', 'Off']}})
def power(arg):
    '''{"group": "Power", "order": 1}'''
    tcp.send('POWER %s\r\n' % arg)

Alternative pattern:

  • Naming convention also works: def local_action_PowerOn(arg=None): ...

Local Events

State this node emits (can be bound by other nodes):

local_event_Status = LocalEvent({'schema': {'type': 'object'}})

# Emit when state changes
local_event_Status.emit({'power': 'On', 'volume': 50})

Remote Bindings

Connect to other nodes:

# Call actions on other nodes
remote_action_DisplayPower = RemoteAction()
remote_action_DisplayPower.call('On')

# Receive events from other nodes
def remote_event_DisplayStatus(arg):
    console.info('Display status: %s' % arg)

Lifecycle Functions

def main():
    '''Called when node starts. Set up initial state.'''
    console.info('Node starting...')

@after_main
def setup():
    '''Called after main() and parameter loading. Configure connections.'''
    tcp.setDest('%s:%s' % (param_ipAddress, param_port))

@at_cleanup
def cleanup():
    '''Called when node shuts down. Clean up resources.'''
    tcp.close()

Network Protocols

TCP, UDP, and HTTP are available via the toolkit. See references/toolkit-api.md for complete documentation with examples.

Timers

# Repeating timer (poll every 30 seconds)
Timer(poll_status, 30)

# One-time delayed call
call(setup_connection, 5)

# Stoppable timer
status_timer = Timer(check_status, 60, stopped=True)
status_timer.start()
status_timer.stop()

Console Logging

console.log("Light gray - verbose/debug")
console.info("Blue - informational")
console.warn("Orange - warning")
console.error("Red - error")

Common Patterns

Device Control with Polling

def poll_status():
    tcp.send('STATUS?\r\n')

Timer(poll_status, 30)

def tcp_received(data):
    if 'POWER=' in data:
        local_event_Status.emit({'power': data.split('=')[1]})

Status Monitoring

local_event_Status = LocalEvent({'schema': {'type': 'object', 'properties': {
    'level': {'type': 'integer'},
    'message': {'type': 'string'}
}}})

_lastReceive = 0

def statusCheck():
    diff = (system_clock() - _lastReceive) / 1000.0
    if diff > 90:
        local_event_Status.emit({'level': 2, 'message': 'No response'})
    else:
        local_event_Status.emit({'level': 0, 'message': 'OK'})

Timer(statusCheck, 60)

Dynamic Action Creation

def build_presets():
    for preset in PRESET_NAMES:
        create_local_action('Preset %s' % preset,
            lambda arg, p=preset: activate_preset(p),
            {'group': 'Presets', 'schema': {'type': 'null'}})

Error Handling

@local_action({})
def riskyOperation(arg):
    try:
        result = perform_operation(arg)
        local_event_Success.emit(result)
    except Exception, e:
        console.error('Operation failed: %s' % e)
        local_event_Error.emit(str(e))

Development Philosophy

  • Simplicity First - Keep code minimal and readable
  • Maintainability > Cleverness - Prefer explicit over implicit
  • DRY - Extract common patterns to helper functions
  • Defensive Coding - Handle network failures gracefully

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

nodel-frontend

No summary provided by upstream source.

Repository SourceNeeds Review
General

nodel-use

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

precog

Trade on prediction markets. Create a local wallet, list markets, check prices, buy and sell outcome shares. Coming soon: create and fund markets directly from this skill.

Archived SourceRecently Updated
Web3

china-sportswear-outdoor-sourcing

Comprehensive sportswear and outdoor equipment sourcing guide for international buyers – provides detailed information about China's athletic apparel, footwear, outdoor gear, and accessories manufacturing clusters, supply chain structure, regional specializations, and industry trends (2026 updated).

Archived SourceRecently Updated