Skip to content

Commit 1102478

Browse files
committed
fix(OpenInverter): Add missing renderCommands and renderErrors methods
The menu items for Commands and Error Log were added in a previous commit, but the actual render methods were never implemented, causing errors: 'Render method not found: renderCommands/renderErrors' Added: - renderCommands(): Device control panel with save/load parameters, start/stop with mode selection, and reset functionality - renderErrors(): Device info and error log display with refresh capability - Supporting methods: deviceSave, deviceLoad, deviceLoadDefaults, deviceStart, deviceStop, deviceReset, loadDeviceInfo, renderDeviceInfoContent Version bumped to 0.4.2
1 parent 9a43b28 commit 1102478

1 file changed

Lines changed: 249 additions & 1 deletion

File tree

Apps/OpenInverter/OpenInverter.app.js

Lines changed: 249 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// {
33
// "name": "OpenInverter",
44
// "id": "openinverter",
5-
// "version": [0, 4, 1],
5+
// "version": [0, 4, 2],
66
// "author": "JetPax",
77
// "description": "OpenInverter debug and configuration tool for motor control parameters, spot values, CAN mapping, and live plotting",
88
// "icon": "sliders",
@@ -729,5 +729,253 @@ class OpenInverterApp {
729729

730730
this.emit('render')
731731
}
732+
733+
/**
734+
* Render Commands panel
735+
* Device control commands: save/load parameters, start/stop, reset
736+
*/
737+
renderCommands() {
738+
return this.html`
739+
<div class="oi-parameters-container">
740+
<h2 style="color: var(--scheme-primary); margin-bottom: 20px;">Device Commands</h2>
741+
742+
<!-- Parameter Storage -->
743+
<div style="margin-bottom: 32px;">
744+
<h3 style="font-size: 16px; margin-bottom: 12px;">Parameter Storage</h3>
745+
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
746+
<button class="primary-button" onclick=${() => this.deviceSave()}>
747+
Save to Flash
748+
</button>
749+
<button class="secondary-button" onclick=${() => this.deviceLoad()}>
750+
Load from Flash
751+
</button>
752+
<button class="secondary-button" onclick=${() => this.deviceLoadDefaults()}>
753+
Load Factory Defaults
754+
</button>
755+
</div>
756+
<p style="color: var(--text-secondary); font-size: 13px; margin-top: 8px;">
757+
Save parameters to persistent storage or restore defaults
758+
</p>
759+
</div>
760+
761+
<!-- Device Control -->
762+
<div style="margin-bottom: 32px;">
763+
<h3 style="font-size: 16px; margin-bottom: 12px;">Device Control</h3>
764+
<div style="display: flex; gap: 12px; align-items: center; flex-wrap: wrap;">
765+
<select id="oi-start-mode" style="padding: 8px; border-radius: 4px; border: 1px solid var(--border-color); background: var(--bg-secondary); color: var(--text-primary);">
766+
<option value="0">Off</option>
767+
<option value="1">Normal</option>
768+
<option value="2">Manual</option>
769+
<option value="3">Boost</option>
770+
<option value="4">Buck</option>
771+
<option value="5">Sine</option>
772+
<option value="6">ACHeat</option>
773+
</select>
774+
<button class="primary-button" onclick=${() => this.deviceStart()}>
775+
Start Device
776+
</button>
777+
<button class="secondary-button" onclick=${() => this.deviceStop()}>
778+
Stop Device
779+
</button>
780+
</div>
781+
<p style="color: var(--text-secondary); font-size: 13px; margin-top: 8px;">
782+
Start device in selected mode or stop operation
783+
</p>
784+
</div>
785+
786+
<!-- System Actions -->
787+
<div>
788+
<h3 style="font-size: 16px; margin-bottom: 12px;">System Actions</h3>
789+
<button class="secondary-button" style="background: #c0392b; color: white;" onclick=${() => this.deviceReset()}>
790+
Reset Device
791+
</button>
792+
<p style="color: var(--text-secondary); font-size: 13px; margin-top: 8px;">
793+
Perform a software reset of the device
794+
</p>
795+
</div>
796+
</div>
797+
`
798+
}
799+
800+
async deviceSave() {
801+
try {
802+
await this.device.execute('from lib.OI_helpers import deviceSave; deviceSave()')
803+
alert('Parameters saved to flash')
804+
} catch (error) {
805+
alert('Failed to save parameters: ' + error.message)
806+
}
807+
}
808+
809+
async deviceLoad() {
810+
try {
811+
await this.device.execute('from lib.OI_helpers import deviceLoad; deviceLoad()')
812+
alert('Parameters loaded from flash')
813+
} catch (error) {
814+
alert('Failed to load parameters: ' + error.message)
815+
}
816+
}
817+
818+
async deviceLoadDefaults() {
819+
if (!confirm('Load factory defaults? This will overwrite all current parameters.')) return
820+
try {
821+
await this.device.execute('from lib.OI_helpers import deviceLoadDefaults; deviceLoadDefaults()')
822+
alert('Factory defaults loaded')
823+
} catch (error) {
824+
alert('Failed to load defaults: ' + error.message)
825+
}
826+
}
827+
828+
async deviceStart() {
829+
const mode = document.getElementById('oi-start-mode')?.value || '1'
830+
try {
831+
await this.device.execute(`from lib.OI_helpers import deviceStart; deviceStart({'mode': ${mode}})`)
832+
alert('Device started in mode ' + mode)
833+
} catch (error) {
834+
alert('Failed to start device: ' + error.message)
835+
}
836+
}
837+
838+
async deviceStop() {
839+
try {
840+
await this.device.execute('from lib.OI_helpers import deviceStop; deviceStop()')
841+
alert('Device stopped')
842+
} catch (error) {
843+
alert('Failed to stop device: ' + error.message)
844+
}
845+
}
846+
847+
async deviceReset() {
848+
if (!confirm('Reset device? This will restart the controller.')) return
849+
try {
850+
await this.device.execute('from lib.OI_helpers import deviceReset; deviceReset()')
851+
alert('Device reset command sent')
852+
} catch (error) {
853+
alert('Failed to reset device: ' + error.message)
854+
}
855+
}
856+
857+
/**
858+
* Render Errors panel
859+
* Display device info and error log
860+
*/
861+
renderErrors() {
862+
// Load device info if not already loaded
863+
if (!this.state.oiDeviceInfo && !this.state.isLoadingDeviceInfo && this.state.isConnected) {
864+
setTimeout(() => this.loadDeviceInfo(), 0)
865+
}
866+
867+
return this.html`
868+
<div class="oi-parameters-container">
869+
<h2 style="color: var(--scheme-primary); margin-bottom: 20px;">Device Information & Error Log</h2>
870+
871+
${this.renderDeviceInfoContent()}
872+
</div>
873+
`
874+
}
875+
876+
renderDeviceInfoContent() {
877+
if (this.state.isLoadingDeviceInfo) {
878+
return this.html`
879+
<div style="text-align: center; padding: 40px;">
880+
<p style="color: var(--text-secondary);">Loading device information...</p>
881+
</div>
882+
`
883+
}
884+
885+
if (!this.state.oiDeviceInfo) {
886+
return this.html`
887+
<div style="text-align: center; padding: 40px;">
888+
<p style="color: var(--text-secondary);">No device information available</p>
889+
<button class="primary-button" style="margin-top: 16px;" onclick=${() => this.loadDeviceInfo()}>
890+
Load Device Info
891+
</button>
892+
</div>
893+
`
894+
}
895+
896+
const info = this.state.oiDeviceInfo
897+
const errors = this.state.oiErrorLog || []
898+
899+
return this.html`
900+
<div>
901+
<!-- Device Info -->
902+
<div style="background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 8px; padding: 16px; margin-bottom: 24px;">
903+
<h3 style="font-size: 16px; margin-bottom: 12px;">Device Info</h3>
904+
<div style="display: grid; grid-template-columns: 150px 1fr; gap: 8px; font-size: 14px;">
905+
<span style="color: var(--text-secondary);">Serial Number:</span>
906+
<span style="font-family: monospace;">${info.serialNumber || 'N/A'}</span>
907+
908+
<span style="color: var(--text-secondary);">Node ID:</span>
909+
<span>${info.nodeId || 'N/A'}</span>
910+
911+
<span style="color: var(--text-secondary);">Bitrate:</span>
912+
<span>${info.bitrate ? (info.bitrate / 1000) + ' kbps' : 'N/A'}</span>
913+
914+
<span style="color: var(--text-secondary);">Uptime:</span>
915+
<span>${info.uptime ? Math.floor(info.uptime / 1000) + ' seconds' : 'N/A'}</span>
916+
</div>
917+
</div>
918+
919+
<!-- Error Log -->
920+
<div>
921+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
922+
<h3 style="font-size: 16px; margin: 0;">Error Log</h3>
923+
<button class="secondary-button" onclick=${() => this.loadDeviceInfo()}>
924+
Refresh
925+
</button>
926+
</div>
927+
928+
${errors.length === 0 ? this.html`
929+
<p style="color: var(--text-secondary); text-align: center; padding: 24px;">
930+
No errors logged
931+
</p>
932+
` : this.html`
933+
<div style="border: 1px solid var(--border-color); border-radius: 4px; overflow: hidden;">
934+
<table style="width: 100%; border-collapse: collapse;">
935+
<thead>
936+
<tr style="background: var(--scheme-primary); color: white;">
937+
<th style="padding: 8px; text-align: left;">Timestamp</th>
938+
<th style="padding: 8px; text-align: left;">Error Code</th>
939+
<th style="padding: 8px; text-align: left;">Description</th>
940+
</tr>
941+
</thead>
942+
<tbody>
943+
${errors.map(err => this.html`
944+
<tr style="border-bottom: 1px solid var(--border-color);">
945+
<td style="padding: 8px; font-family: monospace; font-size: 13px;">${err.timestamp || 'N/A'}</td>
946+
<td style="padding: 8px; font-family: monospace; font-weight: 600;">${err.code || 'N/A'}</td>
947+
<td style="padding: 8px;">${err.description || 'N/A'}</td>
948+
</tr>
949+
`)}
950+
</tbody>
951+
</table>
952+
</div>
953+
`}
954+
</div>
955+
</div>
956+
`
957+
}
958+
959+
async loadDeviceInfo() {
960+
this.state.isLoadingDeviceInfo = true
961+
this.emit('render')
962+
963+
try {
964+
const infoResult = await this.device.execute('from lib.OI_helpers import getDeviceInfo; getDeviceInfo()')
965+
const info = this.device.parseJSON(infoResult)
966+
this.state.oiDeviceInfo = info.ARG || info
967+
968+
const errorResult = await this.device.execute('from lib.OI_helpers import getErrorLog; getErrorLog()')
969+
const errors = this.device.parseJSON(errorResult)
970+
this.state.oiErrorLog = errors.ARG || errors || []
971+
} catch (error) {
972+
console.error('[OI App] Failed to load device info:', error)
973+
this.state.oiDeviceInfo = null
974+
this.state.oiErrorLog = []
975+
} finally {
976+
this.state.isLoadingDeviceInfo = false
977+
this.emit('render')
978+
}
979+
}
732980
}
733981

0 commit comments

Comments
 (0)