npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wethecurious/iotes-curios

v0.1.33

Published

Curios middleware for iotes

Downloads

33

Readme

iotes-curios

This collection of middlewares is designed to provide a redux friendly connection to We The Curious's Curios services for exhibit's implementing the redux pattern. The middleware handles connection to and data retrival from:

  • mqtt iot devices
  • phidget physical input devices
  • exhibit analytics service

Example

There is a basic example here of the usage of this package avaliable on We The Curious bitbucket https://bitbucket.org/wethecurious/playground-usecurios-example/src/master/

Usage

The createCuriosMiddleware export both a middleware and wrapped version of the redux combineReducer function which provides the '@@Curios' reducer to track connection state in the redux store

This is a significant rewrite of the previous brightsign-middleware package. In the long tun it will make it easer to intgrate new devices

Config example

const phidgetTopologoy: TopologyMap<PhidgetStrategyConfig, PhidgetDeviceTypes > = {
  hosts: [{ name: 'testapp/0', host: 'localhost', port: '8888' }],
  devices: [
      {
          hostName: 'testapp/0', //host name of device matches the device with required host
          type: 'RFID_READER',
          name: 'READ/1', // Note that the names must be unique globally across all strategies at this stage
          channel: 1,
      },
      {
          hostName: 'testapp/0',
          type: 'ROTARY_ENCODER',
          name: 'ENCOD/1',
          channel: 2,
      },
  ],
}

const messageTopologoy: TopologyMap<MqttStrategyConfig, MqttDeviceTypes> = {
    hosts: [{ name: 'testapp/0', host: 'localhost', port: '8888' }],
    devices: [
        {
            hostName: 'testapp/0',
            type: 'APP_CHANNEL',
            name: 'READER/1',
            channel: 1,
        },
        {
            hostName: 'testapp/0',
            type: 'EXTERNAL_CHANNEL',
            name: 'ENCODER/1',
            channel: 2,
        },
    ],
  }

const config: CuriosConfig = {
    app: 'app',
    appInstance: 0,
    service: 'service',
    serviceInstance: 0,
    phidget: phidgetTopologoy,
    message: messageTopologoy
} 

Usage example

On Initialisation

const { useCurios, middleware, combineReducers }: CuriosIntegration = createCuriosMiddleware(config)
const reduxStore = createStore(combineReducers({...otherReducers}), applyMiddleware(...middleware))

Within a component

const Component = () => {
  const [ deviceVal, setDeviceVal ] = useCurios()

  return (
      <>
        <p>{deviceVal}</p>
        <button onClick={() => {
          setDeviceVal(
            'ENCODER/1', // Device name to update 
            'UPDATE', // type of update (may not be used by the strategy, depending on the purpose and docs)
            { message: 'test' }, // Payload to send to device
          )
        }}
        />
      </>
  )
}

Adding Devices

Adding Strategies to handle new device types

This is packages is built on iotes, which is a more generalised packages for communication between state management libraries.

Iotes works by routing requests to strategies which hendle device communication. The strategy for phidget22 for example for be found here

https://www.npmjs.com/package/iotes-strategy-phidget22,

support for more more devices can be added by modifying the strategy source or writing a new strategy

The general form of a strategy is as follows

 const strategy = iotesFunctions => hostFactory => DeviceFactory => DeviceFunction

For example

const phidgetStrategy = (
    hostDispatch,
    deviceDispatch,
    hostSubscribe,
    hostDispatch
): HostFactory => async (
    hostConfig: HostConfig<StrategyConfig>,
): Promise<DeviceFactory> => (
    deviceFactory
) => DeviceFunctions

The function of each of the stages is:

  • iotesFunction: is where the iotes commuication channel are injected and should remain as the four fuctions as demonstrated.
  • hostFactory: is where the host connections from the tolopology map are created. This is where you make the connection to the service you are trying to use. This returns a device factory.
  • deviceFactory: This returns a object of functions. Each function create connections to the devices described in the topology map.
  • deviceFunctions: This is the function which creates the connection to the actual device.

The completed strategy should then be able to be passed into the createIotes function and be initialised according to the topology map

Adding strategies to Curios reducer

The reducer connection to iotes is initialised by creating muliple instances of the IotesReactReduxHooks plugin.

  const [ usePhidget, phidgetMiddleware ]: IotesReactReduxHook = createIotesReactReduxHook(
    {...phidget, client: { name: names.complete }}, 
    phidgetStrategy, '@@CURIOS', '@@CURIOS_PHIDGET'
  )
  const [ useMessage, messageMiddleware ]: IotesReactReduxHook = createIotesReactReduxHook(
    { ...message, client: { name: names.complete } }, 
    mqttStrategy, '@@CURIOS', '@@CURIOS_MESSAGE'
  )
  const [ useAnalytics, analyticsMiddleware ]: IotesReactReduxHook = createIotesReactReduxHook(
    {...analytics, client: { name: names.complete }}, 
    mqttStrategy, '@@CURIOS', '@@CURIOS_ANALYTICS'
  )
  //Add a new connection here

  const middlewares = [phidgetMiddleware, messageMiddleware, analyticsMiddleware, /*Add new  middleware here*/]

  return ({
    useCurios: createUseCurios(usePhidget, useMessage, useAnalytics, /*add new hooks here*/), 
    middleware: middlewares, 
    combineReducers
  })

In the actual custom hook you need to manually add the hook handlng at this stage (I couldn't work out how to reliably put it in a loop without violating the rules of hooks)

const createUseCurios = (usePhidget: any, useMessage: any, useAnalytics: any):() => [{}, any] => {
    return () => {
      const [ input, setInput ] = useState({})
      const [ phidget, setPhidget ] = usePhidget()
      const [ message, setMessage ] = useMessage()
      const [ analytics, setAnalytics ] = useAnalytics()
      // Destructure new hooks here 
      const [ output, setOutput ] = useState<DeviceDispatchable<any>>({})

      const setDeviceVal = (
        name: string,
        type: any,
        payload: {[key:string] : unknown},
        meta?: {[key:string] : unknown}, 
        source? :string,
        error?: ErrorDispatchable
      ) => {
        setOutput({...output, ... createDeviceDispatchable(name, type, payload, meta, source, error)})
      }

      useEffect(() => { 
        setInput(phidget) 
      }, [phidget])

      useEffect(() => { 
        setInput(message) 
      }, [message])

      useEffect(() => { 
        setInput(analytics) 
      }, [analytics])

      // Add input method here

      useEffect(() => {
        setMessage(output)
        setPhidget(output)
        // add set hook here
      },[output])

      return [ input, setDeviceVal ]
    }
}

TODO

  • Support for more phidget devices
  • Strategy to talk to mqtt dmx