Skip to content

Commit

Permalink
Refactor component attachment logic and add SD Offline Logger component
Browse files Browse the repository at this point in the history
  • Loading branch information
TonProtofy committed Oct 31, 2024
1 parent 1ff3f11 commit 7a3adbd
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 10 deletions.
31 changes: 22 additions & 9 deletions packages/protodevice/src/device/Device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ class Device {
deviceComponents.esphome.name = deviceName
deviceComponents.protofy = { credentials: this.credentials }

this.components?.forEach((component, i) => {
console.log("🚀 ~ file: Device.ts:62 ~ Device ~ this.components?.forEach ~ component:", component)
if(component){
deviceComponents = component.attach(
!isNaN(parseInt(this.pinTable[i]))
? parseInt(this.pinTable[i])
: this.pinTable[i], deviceComponents, this.components
);
}
this.components?.map((component, i) => ({
component,
pin: !isNaN(parseInt(this.pinTable[i])) ? parseInt(this.pinTable[i]) : this.pinTable[i]
}))
// Sort to ensure "sd_card_component" types are attached last
.sort((a, b) => {
if (a.component?.type === "sd_card_component") return 1;
if (b.component?.type === "sd_card_component") return -1;
return 0;
})
// Attach each component in the sorted order with its associated pin
.forEach(({ component, pin }) => {
if (component) {
deviceComponents = component.attach(pin, deviceComponents, this.components);
}
});

delete deviceComponents.protofy
//console.log("🚀 ~ file: Device.ts:120 ~ Device ~ getComponents ~ deviceComponents:", deviceComponents)
this.componentsTree = deviceComponents
Expand All @@ -50,6 +57,12 @@ class Device {
}
}
})






this.subsystemsTree = this.subsystemsTree.sort((a,b)=>{
if(a.name=="mqtt"){
return -1
Expand Down
79 changes: 79 additions & 0 deletions packages/protodevice/src/device/SdOfflineLogger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { device } from "./Device";

class SdOfflineLogger {
name;
type;
timeId;
jsonFileName;
intervalSeconds;
publishDataWhenOnline;
publishDataTopic;
sensorsArray;

constructor(name, timeId, jsonFileName, intervalSeconds, publishDataWhenOnline, publishDataTopic) {
this.name = name;
this.type = "sd_card_component";
this.timeId = timeId;
this.jsonFileName = jsonFileName;
this.intervalSeconds = intervalSeconds;
this.publishDataWhenOnline = publishDataWhenOnline;
this.publishDataTopic = publishDataTopic;
this.sensorsArray = [];
}

attach(pin, deviceComponents) {
deviceComponents?.sensor?.forEach((sensor) => {
if (sensor.name){
this.sensorsArray.push(sensor.name);
} else if (sensor.id){
this.sensorsArray.push(sensor.id);
}
});

const componentObjects = [
{
name: "external_components",
config: {
//@ts-ignore
source: "github://Protofy-xyz/esphome-components",
refresh: "10s",
components: ["sd_card_component"]
}
},
{
name: "sd_card_component",
config: {
id: this.name,
cs_pin: pin,
time_id: this.timeId,
json_file_name: this.jsonFileName,
interval_seconds: this.intervalSeconds,
publish_data_when_online: this.publishDataWhenOnline,
publish_data_topic: deviceComponents.mqtt?.topic_prefix+this.publishDataTopic,
sensors: this.sensorsArray,
},
},
];

componentObjects.forEach((element) => {
if (!deviceComponents[element.name]) {
deviceComponents[element.name] = element.config;
} else {
if (!Array.isArray(deviceComponents[element.name])) {
deviceComponents[element.name] = [deviceComponents[element.name]];
}
deviceComponents[element.name] = [...deviceComponents[element.name], element.config];
}
});

return deviceComponents;
}

getSubsystem() {
return {}
}
}

export function sdOfflineLogger(name, timeId, jsonFileName, intervalSeconds, publishDataWhenOnline, publishDataTopic) {
return new SdOfflineLogger(name, timeId, jsonFileName, intervalSeconds, publishDataWhenOnline, publishDataTopic);
}
3 changes: 2 additions & 1 deletion packages/protodevice/src/device/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ export * from './MKSServo42D'
export * from './Msa3xx'
export * from './ODrive'
export * from './INA226'
export * from './SntpTime'
export * from './SntpTime'
export * from './SdOfflineLogger'
46 changes: 46 additions & 0 deletions packages/protodevice/src/nodes/SdOfflineLogger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react";
import { Node, Field, HandleOutput, NodeParams } from "protoflow";
import { getColor } from ".";

const SdOfflineLogger = ({ node = {}, nodeData = {}, children, color }: any) => {
const nameErrorMsg = 'Reserved name'
const [name, setName] = React.useState(nodeData['param-1'])
const intervalErrorMsg = 'Add units h/m/s/ms'
const nodeParams: Field[] = [
{
label: 'Name', static: true, field: 'param-1', type: 'input', onBlur: () => { setName(nodeData['param-1']) },
error: nodeData['param-1']?.value?.replace(/['"]+/g, '') == 'sd_card_component' ? nameErrorMsg : null
},
{ label: 'Time ID', static: true, field: 'param-2', type: 'input', },
{ label: 'JSON File Name', static: true, field: 'param-3', type: 'input' },
{
label: 'Interval Seconds', static: true, field: 'param-4', type: 'input',
error: !['h', 'm', 's', 'ms'].includes(nodeData['param-4']?.value?.replace(/['"0-9]+/g, '')) ? intervalErrorMsg : null
},
{ label: 'Publish Data When Online', static: true, field: 'param-5', type: 'boolean' },
{ label: 'Publish Data Topic', static: true, field: 'param-6', type: 'input' },

] as Field[]
return (
<Node node={node} isPreview={!node.id} title='SD offline logger' color={color} id={node.id} skipCustom={true} disableInput disableOutput>
<NodeParams id={node.id} params={nodeParams} />
</Node>
)
}

export default {
id: 'SdOfflineLogger',
type: 'CallExpression',
category: "Utils",
keywords: ["sd", "log", "offline"],
check: (node, nodeData) => node.type == "CallExpression" && nodeData.to?.startsWith('sdOfflineLogger'),
getComponent: (node, nodeData, children) => <SdOfflineLogger color={getColor('SdOfflineLogger')} node={node} nodeData={nodeData} children={children} />,
getInitialData: () => { return { to: 'sdOfflineLogger',
"param-1": { value: "", kind: "StringLiteral" },
"param-2": { value: "", kind: "StringLiteral" },
"param-3": { value: "/offline_data.json", kind: "StringLiteral" },
"param-4": { value: "30s", kind: "StringLiteral" },
"param-5": { value: true, kind: "FalseKeyword" },
"param-6": { value: "/ofline_data", kind: "StringLiteral" },
} }
}
2 changes: 2 additions & 0 deletions packages/protodevice/src/nodes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import ODrive from './ODrive';
import INA226 from './INA226';
import LEDCOutput from './LEDCOutput';
import SntpTime from './SntpTime';
import SdOfflineLogger from './SdOfflineLogger';


const deviceMasks = [
Expand Down Expand Up @@ -81,6 +82,7 @@ const deviceMasks = [
INA226,
LEDCOutput,
SntpTime,
SdOfflineLogger,
]

const masksLength = deviceMasks.length
Expand Down

0 comments on commit 7a3adbd

Please sign in to comment.